diff --git a/kernel/Makefile b/kernel/Makefile index bdd24e8d..bc4fc94a 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -5,6 +5,7 @@ obj-y += module_api.o obj-y += sucompat.o obj-y += selinux/ +obj-y += libsepol/ EXPECTED_SIZE := 0x033b EXPECTED_HASH := 0xb0b91415 diff --git a/kernel/libsepol/.DS_Store b/kernel/libsepol/.DS_Store new file mode 100644 index 00000000..20238e7e Binary files /dev/null and b/kernel/libsepol/.DS_Store differ diff --git a/kernel/libsepol/.gitignore b/kernel/libsepol/.gitignore new file mode 100644 index 00000000..abfb603b --- /dev/null +++ b/kernel/libsepol/.gitignore @@ -0,0 +1,7 @@ +utils/chkcon +utils/sepol_check_access +utils/sepol_compute_av +utils/sepol_compute_member +utils/sepol_compute_relabel +utils/sepol_validate_transition +libsepol.map diff --git a/kernel/libsepol/COPYING b/kernel/libsepol/COPYING new file mode 100644 index 00000000..8add30ad --- /dev/null +++ b/kernel/libsepol/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/kernel/libsepol/Makefile b/kernel/libsepol/Makefile new file mode 100644 index 00000000..df29e20f --- /dev/null +++ b/kernel/libsepol/Makefile @@ -0,0 +1,48 @@ +obj-y += src/assertion.o +obj-y += src/avrule_block.o +obj-y += src/avtab.o +obj-y += src/boolean_record.o +obj-y += src/booleans.o +obj-y += src/conditional.o +obj-y += src/constraint.o +obj-y += src/context.o +obj-y += src/context_record.o +obj-y += src/debug.o +obj-y += src/ebitmap.o +obj-y += src/expand.o +obj-y += src/handle.o +obj-y += src/hashtab.o +obj-y += src/hierarchy.o +# obj-y += src/ibendport_record.o +# obj-y += src/ibendports.o +# obj-y += src/ibpkey_record.o +# obj-y += src/ibpkeys.o +# obj-y += src/iface_record.o +# obj-y += src/interfaces.o +# obj-y += src/kernel_to_cil.o +# obj-y += src/kernel_to_common.o +# obj-y += src/kernel_to_conf.o +obj-y += src/link.o +obj-y += src/mls.o +obj-y += src/module.o +# obj-y += src/module_to_cil.o +obj-y += src/node_record.o +obj-y += src/nodes.o +obj-y += src/optimize.o +obj-y += src/polcaps.o +obj-y += src/policydb.o +obj-y += src/policydb_convert.o +obj-y += src/policydb_public.o +obj-y += src/policydb_validate.o +obj-y += src/port_record.o +obj-y += src/ports.o +obj-y += src/services.o +obj-y += src/sidtab.o +obj-y += src/symtab.o +obj-y += src/user_record.o +obj-y += src/users.o +obj-y += src/util.o +obj-y += src/write.o +obj-y += src/inet_ntop.o + +ccflags-y += -I $(srctree)/$(src)/include \ No newline at end of file diff --git a/kernel/libsepol/VERSION b/kernel/libsepol/VERSION new file mode 100644 index 00000000..2f4b6075 --- /dev/null +++ b/kernel/libsepol/VERSION @@ -0,0 +1 @@ +3.4 diff --git a/kernel/libsepol/cil/.DS_Store b/kernel/libsepol/cil/.DS_Store new file mode 100644 index 00000000..843843c7 Binary files /dev/null and b/kernel/libsepol/cil/.DS_Store differ diff --git a/kernel/libsepol/cil/.gitignore b/kernel/libsepol/cil/.gitignore new file mode 100644 index 00000000..7218d83c --- /dev/null +++ b/kernel/libsepol/cil/.gitignore @@ -0,0 +1,14 @@ +*.swp +*.gcda +*.gcno +*.o +*.a +src/cil_lexer.c +unit_tests +cov +secilc +docs/pdf/ +docs/html/ +docs/man8/ +policy.* +file_contexts diff --git a/kernel/libsepol/cil/include/cil/cil.h b/kernel/libsepol/cil/include/cil/cil.h new file mode 100644 index 00000000..482ca522 --- /dev/null +++ b/kernel/libsepol/cil/include/cil/cil.h @@ -0,0 +1,86 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_H_ +#define CIL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct cil_db; +typedef struct cil_db cil_db_t; + +extern void cil_db_init(cil_db_t **db); +extern void cil_db_destroy(cil_db_t **db); + +extern int cil_add_file(cil_db_t *db, const char *name, const char *data, size_t size); + +extern int cil_compile(cil_db_t *db); +extern int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db); +extern int cil_userprefixes_to_string(cil_db_t *db, char **out, size_t *size); +extern int cil_selinuxusers_to_string(cil_db_t *db, char **out, size_t *size); +extern int cil_filecons_to_string(cil_db_t *db, char **out, size_t *size); +extern void cil_set_disable_dontaudit(cil_db_t *db, int disable_dontaudit); +extern void cil_set_multiple_decls(cil_db_t *db, int multiple_decls); +extern void cil_set_qualified_names(struct cil_db *db, int qualified_names); +extern void cil_set_disable_neverallow(cil_db_t *db, int disable_neverallow); +extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables); +extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown); +extern void cil_set_mls(cil_db_t *db, int mls); +extern void cil_set_attrs_expand_generated(struct cil_db *db, int attrs_expand_generated); +extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_size); +extern void cil_set_target_platform(cil_db_t *db, int target_platform); +extern void cil_set_policy_version(cil_db_t *db, int policy_version); +extern void cil_write_policy_conf(FILE *out, struct cil_db *db); +extern int cil_write_parse_ast(FILE *out, cil_db_t *db); +extern int cil_write_build_ast(FILE *out, cil_db_t *db); +extern int cil_write_resolve_ast(FILE *out, cil_db_t *db); + +enum cil_log_level { + CIL_ERR = 1, + CIL_WARN, + CIL_INFO +}; +extern void cil_set_log_level(enum cil_log_level lvl); +extern void cil_set_log_handler(void (*handler)(int lvl, const char *msg)); + +#ifdef __GNUC__ +__attribute__ ((format(printf, 2, 3))) +#endif +extern void cil_log(enum cil_log_level lvl, const char *msg, ...); + +extern void cil_set_malloc_error_handler(void (*handler)(void)); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/kernel/libsepol/cil/src/cil.c b/kernel/libsepol/cil/src/cil.c new file mode 100644 index 00000000..30074ceb --- /dev/null +++ b/kernel/libsepol/cil/src/cil.c @@ -0,0 +1,2906 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include + +#include +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_symtab.h" +#include "cil_build_ast.h" + +#include "cil_parser.h" +#include "cil_build_ast.h" +#include "cil_resolve_ast.h" +#include "cil_fqn.h" +#include "cil_post.h" +#include "cil_binary.h" +#include "cil_policy.h" +#include "cil_strpool.h" +#include "cil_write_ast.h" + +const int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = { + {64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, + {8, 8, 8, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} +}; + +char *CIL_KEY_CONS_T1; +char *CIL_KEY_CONS_T2; +char *CIL_KEY_CONS_T3; +char *CIL_KEY_CONS_R1; +char *CIL_KEY_CONS_R2; +char *CIL_KEY_CONS_R3; +char *CIL_KEY_CONS_U1; +char *CIL_KEY_CONS_U2; +char *CIL_KEY_CONS_U3; +char *CIL_KEY_CONS_L1; +char *CIL_KEY_CONS_L2; +char *CIL_KEY_CONS_H1; +char *CIL_KEY_CONS_H2; +char *CIL_KEY_AND; +char *CIL_KEY_OR; +char *CIL_KEY_NOT; +char *CIL_KEY_EQ; +char *CIL_KEY_NEQ; +char *CIL_KEY_CONS_DOM; +char *CIL_KEY_CONS_DOMBY; +char *CIL_KEY_CONS_INCOMP; +char *CIL_KEY_CONDTRUE; +char *CIL_KEY_CONDFALSE; +char *CIL_KEY_SELF; +char *CIL_KEY_OBJECT_R; +char *CIL_KEY_STAR; +char *CIL_KEY_TCP; +char *CIL_KEY_UDP; +char *CIL_KEY_DCCP; +char *CIL_KEY_SCTP; +char *CIL_KEY_AUDITALLOW; +char *CIL_KEY_TUNABLEIF; +char *CIL_KEY_ALLOW; +char *CIL_KEY_DONTAUDIT; +char *CIL_KEY_TYPETRANSITION; +char *CIL_KEY_TYPECHANGE; +char *CIL_KEY_CALL; +char *CIL_KEY_TUNABLE; +char *CIL_KEY_XOR; +char *CIL_KEY_ALL; +char *CIL_KEY_RANGE; +char *CIL_KEY_GLOB; +char *CIL_KEY_FILE; +char *CIL_KEY_DIR; +char *CIL_KEY_CHAR; +char *CIL_KEY_BLOCK; +char *CIL_KEY_SOCKET; +char *CIL_KEY_PIPE; +char *CIL_KEY_SYMLINK; +char *CIL_KEY_ANY; +char *CIL_KEY_XATTR; +char *CIL_KEY_TASK; +char *CIL_KEY_TRANS; +char *CIL_KEY_TYPE; +char *CIL_KEY_ROLE; +char *CIL_KEY_USER; +char *CIL_KEY_USERATTRIBUTE; +char *CIL_KEY_USERATTRIBUTESET; +char *CIL_KEY_SENSITIVITY; +char *CIL_KEY_CATEGORY; +char *CIL_KEY_CATSET; +char *CIL_KEY_LEVEL; +char *CIL_KEY_LEVELRANGE; +char *CIL_KEY_CLASS; +char *CIL_KEY_IPADDR; +char *CIL_KEY_MAP_CLASS; +char *CIL_KEY_CLASSPERMISSION; +char *CIL_KEY_BOOL; +char *CIL_KEY_STRING; +char *CIL_KEY_NAME; +char *CIL_KEY_SOURCE; +char *CIL_KEY_TARGET; +char *CIL_KEY_LOW; +char *CIL_KEY_HIGH; +char *CIL_KEY_LOW_HIGH; +char *CIL_KEY_GLBLUB; +char *CIL_KEY_HANDLEUNKNOWN; +char *CIL_KEY_HANDLEUNKNOWN_ALLOW; +char *CIL_KEY_HANDLEUNKNOWN_DENY; +char *CIL_KEY_HANDLEUNKNOWN_REJECT; +char *CIL_KEY_MACRO; +char *CIL_KEY_IN; +char *CIL_KEY_IN_BEFORE; +char *CIL_KEY_IN_AFTER; +char *CIL_KEY_MLS; +char *CIL_KEY_DEFAULTRANGE; +char *CIL_KEY_BLOCKINHERIT; +char *CIL_KEY_BLOCKABSTRACT; +char *CIL_KEY_CLASSORDER; +char *CIL_KEY_CLASSMAPPING; +char *CIL_KEY_CLASSPERMISSIONSET; +char *CIL_KEY_COMMON; +char *CIL_KEY_CLASSCOMMON; +char *CIL_KEY_SID; +char *CIL_KEY_SIDCONTEXT; +char *CIL_KEY_SIDORDER; +char *CIL_KEY_USERLEVEL; +char *CIL_KEY_USERRANGE; +char *CIL_KEY_USERBOUNDS; +char *CIL_KEY_USERPREFIX; +char *CIL_KEY_SELINUXUSER; +char *CIL_KEY_SELINUXUSERDEFAULT; +char *CIL_KEY_TYPEATTRIBUTE; +char *CIL_KEY_TYPEATTRIBUTESET; +char *CIL_KEY_EXPANDTYPEATTRIBUTE; +char *CIL_KEY_TYPEALIAS; +char *CIL_KEY_TYPEALIASACTUAL; +char *CIL_KEY_TYPEBOUNDS; +char *CIL_KEY_TYPEPERMISSIVE; +char *CIL_KEY_RANGETRANSITION; +char *CIL_KEY_USERROLE; +char *CIL_KEY_ROLETYPE; +char *CIL_KEY_ROLETRANSITION; +char *CIL_KEY_ROLEALLOW; +char *CIL_KEY_ROLEATTRIBUTE; +char *CIL_KEY_ROLEATTRIBUTESET; +char *CIL_KEY_ROLEBOUNDS; +char *CIL_KEY_BOOLEANIF; +char *CIL_KEY_NEVERALLOW; +char *CIL_KEY_TYPEMEMBER; +char *CIL_KEY_SENSALIAS; +char *CIL_KEY_SENSALIASACTUAL; +char *CIL_KEY_CATALIAS; +char *CIL_KEY_CATALIASACTUAL; +char *CIL_KEY_CATORDER; +char *CIL_KEY_SENSITIVITYORDER; +char *CIL_KEY_SENSCAT; +char *CIL_KEY_CONSTRAIN; +char *CIL_KEY_MLSCONSTRAIN; +char *CIL_KEY_VALIDATETRANS; +char *CIL_KEY_MLSVALIDATETRANS; +char *CIL_KEY_CONTEXT; +char *CIL_KEY_FILECON; +char *CIL_KEY_IBPKEYCON; +char *CIL_KEY_IBENDPORTCON; +char *CIL_KEY_PORTCON; +char *CIL_KEY_NODECON; +char *CIL_KEY_GENFSCON; +char *CIL_KEY_NETIFCON; +char *CIL_KEY_PIRQCON; +char *CIL_KEY_IOMEMCON; +char *CIL_KEY_IOPORTCON; +char *CIL_KEY_PCIDEVICECON; +char *CIL_KEY_DEVICETREECON; +char *CIL_KEY_FSUSE; +char *CIL_KEY_POLICYCAP; +char *CIL_KEY_OPTIONAL; +char *CIL_KEY_DEFAULTUSER; +char *CIL_KEY_DEFAULTROLE; +char *CIL_KEY_DEFAULTTYPE; +char *CIL_KEY_ROOT; +char *CIL_KEY_NODE; +char *CIL_KEY_PERM; +char *CIL_KEY_ALLOWX; +char *CIL_KEY_AUDITALLOWX; +char *CIL_KEY_DONTAUDITX; +char *CIL_KEY_NEVERALLOWX; +char *CIL_KEY_PERMISSIONX; +char *CIL_KEY_IOCTL; +char *CIL_KEY_UNORDERED; +char *CIL_KEY_SRC_INFO; +char *CIL_KEY_SRC_CIL; +char *CIL_KEY_SRC_HLL_LMS; +char *CIL_KEY_SRC_HLL_LMX; +char *CIL_KEY_SRC_HLL_LME; + +static void cil_init_keys(void) +{ + /* Initialize CIL Keys into strpool */ + CIL_KEY_CONS_T1 = cil_strpool_add("t1"); + CIL_KEY_CONS_T2 = cil_strpool_add("t2"); + CIL_KEY_CONS_T3 = cil_strpool_add("t3"); + CIL_KEY_CONS_R1 = cil_strpool_add("r1"); + CIL_KEY_CONS_R2 = cil_strpool_add("r2"); + CIL_KEY_CONS_R3 = cil_strpool_add("r3"); + CIL_KEY_CONS_U1 = cil_strpool_add("u1"); + CIL_KEY_CONS_U2 = cil_strpool_add("u2"); + CIL_KEY_CONS_U3 = cil_strpool_add("u3"); + CIL_KEY_CONS_L1 = cil_strpool_add("l1"); + CIL_KEY_CONS_L2 = cil_strpool_add("l2"); + CIL_KEY_CONS_H1 = cil_strpool_add("h1"); + CIL_KEY_CONS_H2 = cil_strpool_add("h2"); + CIL_KEY_AND = cil_strpool_add("and"); + CIL_KEY_OR = cil_strpool_add("or"); + CIL_KEY_NOT = cil_strpool_add("not"); + CIL_KEY_EQ = cil_strpool_add("eq"); + CIL_KEY_NEQ = cil_strpool_add("neq"); + CIL_KEY_CONS_DOM = cil_strpool_add("dom"); + CIL_KEY_CONS_DOMBY = cil_strpool_add("domby"); + CIL_KEY_CONS_INCOMP = cil_strpool_add("incomp"); + CIL_KEY_CONDTRUE = cil_strpool_add("true"); + CIL_KEY_CONDFALSE = cil_strpool_add("false"); + CIL_KEY_SELF = cil_strpool_add("self"); + CIL_KEY_OBJECT_R = cil_strpool_add("object_r"); + CIL_KEY_STAR = cil_strpool_add("*"); + CIL_KEY_UDP = cil_strpool_add("udp"); + CIL_KEY_TCP = cil_strpool_add("tcp"); + CIL_KEY_DCCP = cil_strpool_add("dccp"); + CIL_KEY_SCTP = cil_strpool_add("sctp"); + CIL_KEY_AUDITALLOW = cil_strpool_add("auditallow"); + CIL_KEY_TUNABLEIF = cil_strpool_add("tunableif"); + CIL_KEY_ALLOW = cil_strpool_add("allow"); + CIL_KEY_DONTAUDIT = cil_strpool_add("dontaudit"); + CIL_KEY_TYPETRANSITION = cil_strpool_add("typetransition"); + CIL_KEY_TYPECHANGE = cil_strpool_add("typechange"); + CIL_KEY_CALL = cil_strpool_add("call"); + CIL_KEY_TUNABLE = cil_strpool_add("tunable"); + CIL_KEY_XOR = cil_strpool_add("xor"); + CIL_KEY_ALL = cil_strpool_add("all"); + CIL_KEY_RANGE = cil_strpool_add("range"); + CIL_KEY_TYPE = cil_strpool_add("type"); + CIL_KEY_ROLE = cil_strpool_add("role"); + CIL_KEY_USER = cil_strpool_add("user"); + CIL_KEY_USERATTRIBUTE = cil_strpool_add("userattribute"); + CIL_KEY_USERATTRIBUTESET = cil_strpool_add("userattributeset"); + CIL_KEY_SENSITIVITY = cil_strpool_add("sensitivity"); + CIL_KEY_CATEGORY = cil_strpool_add("category"); + CIL_KEY_CATSET = cil_strpool_add("categoryset"); + CIL_KEY_LEVEL = cil_strpool_add("level"); + CIL_KEY_LEVELRANGE = cil_strpool_add("levelrange"); + CIL_KEY_CLASS = cil_strpool_add("class"); + CIL_KEY_IPADDR = cil_strpool_add("ipaddr"); + CIL_KEY_MAP_CLASS = cil_strpool_add("classmap"); + CIL_KEY_CLASSPERMISSION = cil_strpool_add("classpermission"); + CIL_KEY_BOOL = cil_strpool_add("boolean"); + CIL_KEY_STRING = cil_strpool_add("string"); + CIL_KEY_NAME = cil_strpool_add("name"); + CIL_KEY_HANDLEUNKNOWN = cil_strpool_add("handleunknown"); + CIL_KEY_HANDLEUNKNOWN_ALLOW = cil_strpool_add("allow"); + CIL_KEY_HANDLEUNKNOWN_DENY = cil_strpool_add("deny"); + CIL_KEY_HANDLEUNKNOWN_REJECT = cil_strpool_add("reject"); + CIL_KEY_BLOCKINHERIT = cil_strpool_add("blockinherit"); + CIL_KEY_BLOCKABSTRACT = cil_strpool_add("blockabstract"); + CIL_KEY_CLASSORDER = cil_strpool_add("classorder"); + CIL_KEY_CLASSMAPPING = cil_strpool_add("classmapping"); + CIL_KEY_CLASSPERMISSIONSET = cil_strpool_add("classpermissionset"); + CIL_KEY_COMMON = cil_strpool_add("common"); + CIL_KEY_CLASSCOMMON = cil_strpool_add("classcommon"); + CIL_KEY_SID = cil_strpool_add("sid"); + CIL_KEY_SIDCONTEXT = cil_strpool_add("sidcontext"); + CIL_KEY_SIDORDER = cil_strpool_add("sidorder"); + CIL_KEY_USERLEVEL = cil_strpool_add("userlevel"); + CIL_KEY_USERRANGE = cil_strpool_add("userrange"); + CIL_KEY_USERBOUNDS = cil_strpool_add("userbounds"); + CIL_KEY_USERPREFIX = cil_strpool_add("userprefix"); + CIL_KEY_SELINUXUSER = cil_strpool_add("selinuxuser"); + CIL_KEY_SELINUXUSERDEFAULT = cil_strpool_add("selinuxuserdefault"); + CIL_KEY_TYPEATTRIBUTE = cil_strpool_add("typeattribute"); + CIL_KEY_TYPEATTRIBUTESET = cil_strpool_add("typeattributeset"); + CIL_KEY_EXPANDTYPEATTRIBUTE = cil_strpool_add("expandtypeattribute"); + CIL_KEY_TYPEALIAS = cil_strpool_add("typealias"); + CIL_KEY_TYPEALIASACTUAL = cil_strpool_add("typealiasactual"); + CIL_KEY_TYPEBOUNDS = cil_strpool_add("typebounds"); + CIL_KEY_TYPEPERMISSIVE = cil_strpool_add("typepermissive"); + CIL_KEY_RANGETRANSITION = cil_strpool_add("rangetransition"); + CIL_KEY_USERROLE = cil_strpool_add("userrole"); + CIL_KEY_ROLETYPE = cil_strpool_add("roletype"); + CIL_KEY_ROLETRANSITION = cil_strpool_add("roletransition"); + CIL_KEY_ROLEALLOW = cil_strpool_add("roleallow"); + CIL_KEY_ROLEATTRIBUTE = cil_strpool_add("roleattribute"); + CIL_KEY_ROLEATTRIBUTESET = cil_strpool_add("roleattributeset"); + CIL_KEY_ROLEBOUNDS = cil_strpool_add("rolebounds"); + CIL_KEY_BOOLEANIF = cil_strpool_add("booleanif"); + CIL_KEY_NEVERALLOW = cil_strpool_add("neverallow"); + CIL_KEY_TYPEMEMBER = cil_strpool_add("typemember"); + CIL_KEY_SENSALIAS = cil_strpool_add("sensitivityalias"); + CIL_KEY_SENSALIASACTUAL = cil_strpool_add("sensitivityaliasactual"); + CIL_KEY_CATALIAS = cil_strpool_add("categoryalias"); + CIL_KEY_CATALIASACTUAL = cil_strpool_add("categoryaliasactual"); + CIL_KEY_CATORDER = cil_strpool_add("categoryorder"); + CIL_KEY_SENSITIVITYORDER = cil_strpool_add("sensitivityorder"); + CIL_KEY_SENSCAT = cil_strpool_add("sensitivitycategory"); + CIL_KEY_CONSTRAIN = cil_strpool_add("constrain"); + CIL_KEY_MLSCONSTRAIN = cil_strpool_add("mlsconstrain"); + CIL_KEY_VALIDATETRANS = cil_strpool_add("validatetrans"); + CIL_KEY_MLSVALIDATETRANS = cil_strpool_add("mlsvalidatetrans"); + CIL_KEY_CONTEXT = cil_strpool_add("context"); + CIL_KEY_FILECON = cil_strpool_add("filecon"); + CIL_KEY_IBPKEYCON = cil_strpool_add("ibpkeycon"); + CIL_KEY_IBENDPORTCON = cil_strpool_add("ibendportcon"); + CIL_KEY_PORTCON = cil_strpool_add("portcon"); + CIL_KEY_NODECON = cil_strpool_add("nodecon"); + CIL_KEY_GENFSCON = cil_strpool_add("genfscon"); + CIL_KEY_NETIFCON = cil_strpool_add("netifcon"); + CIL_KEY_PIRQCON = cil_strpool_add("pirqcon"); + CIL_KEY_IOMEMCON = cil_strpool_add("iomemcon"); + CIL_KEY_IOPORTCON = cil_strpool_add("ioportcon"); + CIL_KEY_PCIDEVICECON = cil_strpool_add("pcidevicecon"); + CIL_KEY_DEVICETREECON = cil_strpool_add("devicetreecon"); + CIL_KEY_FSUSE = cil_strpool_add("fsuse"); + CIL_KEY_POLICYCAP = cil_strpool_add("policycap"); + CIL_KEY_OPTIONAL = cil_strpool_add("optional"); + CIL_KEY_DEFAULTUSER = cil_strpool_add("defaultuser"); + CIL_KEY_DEFAULTROLE = cil_strpool_add("defaultrole"); + CIL_KEY_DEFAULTTYPE = cil_strpool_add("defaulttype"); + CIL_KEY_MACRO = cil_strpool_add("macro"); + CIL_KEY_IN = cil_strpool_add("in"); + CIL_KEY_IN_BEFORE = cil_strpool_add("before"); + CIL_KEY_IN_AFTER = cil_strpool_add("after"); + CIL_KEY_MLS = cil_strpool_add("mls"); + CIL_KEY_DEFAULTRANGE = cil_strpool_add("defaultrange"); + CIL_KEY_GLOB = cil_strpool_add("*"); + CIL_KEY_FILE = cil_strpool_add("file"); + CIL_KEY_DIR = cil_strpool_add("dir"); + CIL_KEY_CHAR = cil_strpool_add("char"); + CIL_KEY_BLOCK = cil_strpool_add("block"); + CIL_KEY_SOCKET = cil_strpool_add("socket"); + CIL_KEY_PIPE = cil_strpool_add("pipe"); + CIL_KEY_SYMLINK = cil_strpool_add("symlink"); + CIL_KEY_ANY = cil_strpool_add("any"); + CIL_KEY_XATTR = cil_strpool_add("xattr"); + CIL_KEY_TASK = cil_strpool_add("task"); + CIL_KEY_TRANS = cil_strpool_add("trans"); + CIL_KEY_SOURCE = cil_strpool_add("source"); + CIL_KEY_TARGET = cil_strpool_add("target"); + CIL_KEY_LOW = cil_strpool_add("low"); + CIL_KEY_HIGH = cil_strpool_add("high"); + CIL_KEY_LOW_HIGH = cil_strpool_add("low-high"); + CIL_KEY_GLBLUB = cil_strpool_add("glblub"); + CIL_KEY_ROOT = cil_strpool_add(""); + CIL_KEY_NODE = cil_strpool_add(""); + CIL_KEY_PERM = cil_strpool_add("perm"); + CIL_KEY_ALLOWX = cil_strpool_add("allowx"); + CIL_KEY_AUDITALLOWX = cil_strpool_add("auditallowx"); + CIL_KEY_DONTAUDITX = cil_strpool_add("dontauditx"); + CIL_KEY_NEVERALLOWX = cil_strpool_add("neverallowx"); + CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx"); + CIL_KEY_IOCTL = cil_strpool_add("ioctl"); + CIL_KEY_UNORDERED = cil_strpool_add("unordered"); + CIL_KEY_SRC_INFO = cil_strpool_add(""); + CIL_KEY_SRC_CIL = cil_strpool_add("cil"); + CIL_KEY_SRC_HLL_LMS = cil_strpool_add("lms"); + CIL_KEY_SRC_HLL_LMX = cil_strpool_add("lmx"); + CIL_KEY_SRC_HLL_LME = cil_strpool_add("lme"); +} + +void cil_db_init(struct cil_db **db) +{ + *db = cil_malloc(sizeof(**db)); + + cil_strpool_init(); + cil_init_keys(); + + cil_tree_init(&(*db)->parse); + cil_tree_init(&(*db)->ast); + cil_root_init((struct cil_root **)&(*db)->ast->root->data); + (*db)->sidorder = NULL; + (*db)->classorder = NULL; + (*db)->catorder = NULL; + (*db)->sensitivityorder = NULL; + cil_sort_init(&(*db)->netifcon); + cil_sort_init(&(*db)->genfscon); + cil_sort_init(&(*db)->filecon); + cil_sort_init(&(*db)->nodecon); + cil_sort_init(&(*db)->ibpkeycon); + cil_sort_init(&(*db)->ibendportcon); + cil_sort_init(&(*db)->portcon); + cil_sort_init(&(*db)->pirqcon); + cil_sort_init(&(*db)->iomemcon); + cil_sort_init(&(*db)->ioportcon); + cil_sort_init(&(*db)->pcidevicecon); + cil_sort_init(&(*db)->devicetreecon); + cil_sort_init(&(*db)->fsuse); + cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM); + cil_list_init(&(*db)->selinuxusers, CIL_LIST_ITEM); + cil_list_init(&(*db)->names, CIL_LIST_ITEM); + + cil_type_init(&(*db)->selftype); + (*db)->selftype->datum.name = CIL_KEY_SELF; + (*db)->selftype->datum.fqn = CIL_KEY_SELF; + (*db)->num_types_and_attrs = 0; + (*db)->num_classes = 0; + (*db)->num_types = 0; + (*db)->num_roles = 0; + (*db)->num_users = 0; + (*db)->num_cats = 0; + (*db)->val_to_type = NULL; + (*db)->val_to_role = NULL; + (*db)->val_to_user = NULL; + + (*db)->disable_dontaudit = CIL_FALSE; + (*db)->disable_neverallow = CIL_FALSE; + (*db)->attrs_expand_generated = CIL_FALSE; + (*db)->attrs_expand_size = 1; + (*db)->preserve_tunables = CIL_FALSE; + (*db)->handle_unknown = -1; + (*db)->mls = -1; + (*db)->multiple_decls = CIL_FALSE; + (*db)->qualified_names = CIL_FALSE; + (*db)->target_platform = SEPOL_TARGET_SELINUX; + (*db)->policy_version = POLICYDB_VERSION_MAX; +} + +void cil_db_destroy(struct cil_db **db) +{ + if (db == NULL || *db == NULL) { + return; + } + + cil_tree_destroy(&(*db)->parse); + cil_tree_destroy(&(*db)->ast); + cil_list_destroy(&(*db)->sidorder, CIL_FALSE); + cil_list_destroy(&(*db)->classorder, CIL_FALSE); + cil_list_destroy(&(*db)->catorder, CIL_FALSE); + cil_list_destroy(&(*db)->sensitivityorder, CIL_FALSE); + cil_sort_destroy(&(*db)->netifcon); + cil_sort_destroy(&(*db)->genfscon); + cil_sort_destroy(&(*db)->filecon); + cil_sort_destroy(&(*db)->nodecon); + cil_sort_destroy(&(*db)->ibpkeycon); + cil_sort_destroy(&(*db)->ibendportcon); + cil_sort_destroy(&(*db)->portcon); + cil_sort_destroy(&(*db)->pirqcon); + cil_sort_destroy(&(*db)->iomemcon); + cil_sort_destroy(&(*db)->ioportcon); + cil_sort_destroy(&(*db)->pcidevicecon); + cil_sort_destroy(&(*db)->devicetreecon); + cil_sort_destroy(&(*db)->fsuse); + cil_list_destroy(&(*db)->userprefixes, CIL_FALSE); + cil_list_destroy(&(*db)->selinuxusers, CIL_FALSE); + cil_list_destroy(&(*db)->names, CIL_TRUE); + + cil_destroy_type((*db)->selftype); + + cil_strpool_destroy(); + free((*db)->val_to_type); + free((*db)->val_to_role); + free((*db)->val_to_user); + + free(*db); + *db = NULL; +} + +void cil_root_init(struct cil_root **root) +{ + struct cil_root *r = cil_malloc(sizeof(*r)); + cil_symtab_array_init(r->symtab, cil_sym_sizes[CIL_SYM_ARRAY_ROOT]); + + *root = r; +} + +void cil_root_destroy(struct cil_root *root) +{ + if (root == NULL) { + return; + } + cil_symtab_array_destroy(root->symtab); + free(root); +} + +int cil_add_file(cil_db_t *db, const char *name, const char *data, size_t size) +{ + char *buffer = NULL; + int rc; + + cil_log(CIL_INFO, "Parsing %s\n", name); + + buffer = cil_malloc(size + 2); + memcpy(buffer, data, size); + memset(buffer + size, 0, 2); + + rc = cil_parser(name, buffer, size + 2, &db->parse); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to parse %s\n", name); + goto exit; + } + + free(buffer); + buffer = NULL; + + rc = SEPOL_OK; + +exit: + free(buffer); + + return rc; +} + +int cil_compile(struct cil_db *db) +{ + int rc = SEPOL_ERR; + + if (db == NULL) { + goto exit; + } + + cil_log(CIL_INFO, "Building AST from Parse Tree\n"); + rc = cil_build_ast(db, db->parse->root, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to build AST\n"); + goto exit; + } + + cil_log(CIL_INFO, "Destroying Parse Tree\n"); + cil_tree_destroy(&db->parse); + + cil_log(CIL_INFO, "Resolving AST\n"); + rc = cil_resolve_ast(db, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve AST\n"); + goto exit; + } + + cil_log(CIL_INFO, "Qualifying Names\n"); + rc = cil_fqn_qualify(db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to qualify names\n"); + goto exit; + } + + cil_log(CIL_INFO, "Compile post process\n"); + rc = cil_post_process(db); + if (rc != SEPOL_OK ) { + cil_log(CIL_ERR, "Post process failed\n"); + goto exit; + } + +exit: + + return rc; +} + +int cil_write_parse_ast(FILE *out, cil_db_t *db) +{ + int rc = SEPOL_ERR; + + if (db == NULL) { + goto exit; + } + + cil_log(CIL_INFO, "Writing Parse AST\n"); + rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_PARSE, db->parse->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to write parse ast\n"); + goto exit; + } + +exit: + return rc; +} + +int cil_write_build_ast(FILE *out, cil_db_t *db) +{ + int rc = SEPOL_ERR; + + if (db == NULL) { + goto exit; + } + + cil_log(CIL_INFO, "Building AST from Parse Tree\n"); + rc = cil_build_ast(db, db->parse->root, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to build ast\n"); + goto exit; + } + + cil_log(CIL_INFO, "Destroying Parse Tree\n"); + cil_tree_destroy(&db->parse); + + cil_log(CIL_INFO, "Writing Build AST\n"); + rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_BUILD, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to write build ast\n"); + goto exit; + } + +exit: + return rc; +} + +int cil_write_resolve_ast(FILE *out, cil_db_t *db) +{ + int rc = SEPOL_ERR; + + if (db == NULL) { + goto exit; + } + + cil_log(CIL_INFO, "Building AST from Parse Tree\n"); + rc = cil_build_ast(db, db->parse->root, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to build ast\n"); + goto exit; + } + + cil_log(CIL_INFO, "Destroying Parse Tree\n"); + cil_tree_destroy(&db->parse); + + cil_log(CIL_INFO, "Resolving AST\n"); + rc = cil_resolve_ast(db, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve ast\n"); + goto exit; + } + + cil_log(CIL_INFO, "Qualifying Names\n"); + rc = cil_fqn_qualify(db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to qualify names\n"); + goto exit; + } + + cil_log(CIL_INFO, "Writing Resolve AST\n"); + rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_RESOLVE, db->ast->root); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to write resolve ast\n"); + goto exit; + } + +exit: + return rc; +} + +int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db) +{ + int rc; + + cil_log(CIL_INFO, "Building policy binary\n"); + rc = cil_binary_create(db, sepol_db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to generate binary\n"); + goto exit; + } + +exit: + return rc; +} + +void cil_write_policy_conf(FILE *out, struct cil_db *db) +{ + cil_log(CIL_INFO, "Writing policy.conf file\n"); + cil_gen_policy(out, db); +} + +void cil_destroy_data(void **data, enum cil_flavor flavor) +{ + if (*data == NULL) { + return; + } + + switch(flavor) { + case CIL_NONE: + break; + case CIL_ROOT: + cil_root_destroy(*data); + break; + case CIL_NODE: + break; + case CIL_STRING: + break; + case CIL_DATUM: + break; + case CIL_LIST: + cil_list_destroy(*data, CIL_FALSE); + break; + case CIL_LIST_ITEM: + break; + case CIL_PARAM: + cil_destroy_param(*data); + break; + case CIL_ARGS: + cil_destroy_args(*data); + break; + case CIL_BLOCK: + cil_destroy_block(*data); + break; + case CIL_BLOCKINHERIT: + cil_destroy_blockinherit(*data); + break; + case CIL_BLOCKABSTRACT: + cil_destroy_blockabstract(*data); + break; + case CIL_IN: + cil_destroy_in(*data); + break; + case CIL_MACRO: + cil_destroy_macro(*data); + break; + case CIL_CALL: + cil_destroy_call(*data); + break; + case CIL_OPTIONAL: + cil_destroy_optional(*data); + break; + case CIL_BOOL: + cil_destroy_bool(*data); + break; + case CIL_BOOLEANIF: + cil_destroy_boolif(*data); + break; + case CIL_TUNABLE: + cil_destroy_tunable(*data); + break; + case CIL_TUNABLEIF: + cil_destroy_tunif(*data); + break; + case CIL_CONDBLOCK: + cil_destroy_condblock(*data); + break; + case CIL_CONDTRUE: + break; + case CIL_CONDFALSE: + break; + case CIL_PERM: + case CIL_MAP_PERM: + cil_destroy_perm(*data); + break; + case CIL_COMMON: + case CIL_CLASS: + case CIL_MAP_CLASS: + cil_destroy_class(*data); + break; + case CIL_CLASSORDER: + cil_destroy_classorder(*data); + break; + case CIL_CLASSPERMISSION: + cil_destroy_classpermission(*data); + break; + case CIL_CLASSCOMMON: + cil_destroy_classcommon(*data); + break; + case CIL_CLASSMAPPING: + cil_destroy_classmapping(*data); + break; + case CIL_CLASSPERMS: + cil_destroy_classperms(*data); + break; + case CIL_CLASSPERMS_SET: + cil_destroy_classperms_set(*data); + break; + case CIL_CLASSPERMISSIONSET: + cil_destroy_classpermissionset(*data); + break; + case CIL_USER: + cil_destroy_user(*data); + break; + case CIL_USERATTRIBUTE: + cil_destroy_userattribute(*data); + break; + case CIL_USERATTRIBUTESET: + cil_destroy_userattributeset(*data); + break; + case CIL_USERPREFIX: + cil_destroy_userprefix(*data); + break; + case CIL_USERROLE: + cil_destroy_userrole(*data); + break; + case CIL_USERLEVEL: + cil_destroy_userlevel(*data); + break; + case CIL_USERRANGE: + cil_destroy_userrange(*data); + break; + case CIL_USERBOUNDS: + cil_destroy_bounds(*data); + break; + case CIL_SELINUXUSER: + case CIL_SELINUXUSERDEFAULT: + cil_destroy_selinuxuser(*data); + break; + case CIL_ROLE: + cil_destroy_role(*data); + break; + case CIL_ROLEATTRIBUTE: + cil_destroy_roleattribute(*data); + break; + case CIL_ROLEATTRIBUTESET: + cil_destroy_roleattributeset(*data); + break; + case CIL_ROLETYPE: + cil_destroy_roletype(*data); + break; + case CIL_ROLEBOUNDS: + cil_destroy_bounds(*data); + break; + case CIL_TYPE: + cil_destroy_type(*data); + break; + case CIL_TYPEATTRIBUTE: + cil_destroy_typeattribute(*data); + break; + case CIL_TYPEALIAS: + cil_destroy_alias(*data); + break; + case CIL_TYPEATTRIBUTESET: + cil_destroy_typeattributeset(*data); + break; + case CIL_EXPANDTYPEATTRIBUTE: + cil_destroy_expandtypeattribute(*data); + break; + case CIL_TYPEALIASACTUAL: + cil_destroy_aliasactual(*data); + break; + case CIL_TYPEBOUNDS: + cil_destroy_bounds(*data); + break; + case CIL_TYPEPERMISSIVE: + cil_destroy_typepermissive(*data); + break; + case CIL_SENS: + cil_destroy_sensitivity(*data); + break; + case CIL_SENSALIAS: + cil_destroy_alias(*data); + break; + case CIL_SENSALIASACTUAL: + cil_destroy_aliasactual(*data); + break; + case CIL_SENSITIVITYORDER: + cil_destroy_sensitivityorder(*data); + break; + case CIL_SENSCAT: + cil_destroy_senscat(*data); + break; + case CIL_CAT: + cil_destroy_category(*data); + break; + case CIL_CATSET: + cil_destroy_catset(*data); + break; + case CIL_CATALIAS: + cil_destroy_alias(*data); + break; + case CIL_CATALIASACTUAL: + cil_destroy_aliasactual(*data); + break; + case CIL_CATORDER: + cil_destroy_catorder(*data); + break; + case CIL_LEVEL: + cil_destroy_level(*data); + break; + case CIL_LEVELRANGE: + cil_destroy_levelrange(*data); + break; + case CIL_SID: + cil_destroy_sid(*data); + break; + case CIL_SIDORDER: + cil_destroy_sidorder(*data); + break; + case CIL_NAME: + cil_destroy_name(*data); + break; + case CIL_ROLEALLOW: + cil_destroy_roleallow(*data); + break; + case CIL_AVRULE: + case CIL_AVRULEX: + cil_destroy_avrule(*data); + break; + case CIL_PERMISSIONX: + cil_destroy_permissionx(*data); + break; + case CIL_ROLETRANSITION: + cil_destroy_roletransition(*data); + break; + case CIL_TYPE_RULE: + cil_destroy_type_rule(*data); + break; + case CIL_NAMETYPETRANSITION: + cil_destroy_typetransition(*data); + break; + case CIL_RANGETRANSITION: + cil_destroy_rangetransition(*data); + break; + case CIL_CONSTRAIN: + cil_destroy_constrain(*data); + break; + case CIL_MLSCONSTRAIN: + cil_destroy_constrain(*data); + break; + case CIL_VALIDATETRANS: + case CIL_MLSVALIDATETRANS: + cil_destroy_validatetrans(*data); + break; + case CIL_CONTEXT: + cil_destroy_context(*data); + break; + case CIL_IPADDR: + cil_destroy_ipaddr(*data); + break; + case CIL_SIDCONTEXT: + cil_destroy_sidcontext(*data); + break; + case CIL_FSUSE: + cil_destroy_fsuse(*data); + break; + case CIL_FILECON: + cil_destroy_filecon(*data); + break; + case CIL_IBPKEYCON: + cil_destroy_ibpkeycon(*data); + break; + case CIL_PORTCON: + cil_destroy_portcon(*data); + break; + case CIL_IBENDPORTCON: + cil_destroy_ibendportcon(*data); + break; + case CIL_NODECON: + cil_destroy_nodecon(*data); + break; + case CIL_GENFSCON: + cil_destroy_genfscon(*data); + break; + case CIL_NETIFCON: + cil_destroy_netifcon(*data); + break; + case CIL_PIRQCON: + cil_destroy_pirqcon(*data); + break; + case CIL_IOMEMCON: + cil_destroy_iomemcon(*data); + break; + case CIL_IOPORTCON: + cil_destroy_ioportcon(*data); + break; + case CIL_PCIDEVICECON: + cil_destroy_pcidevicecon(*data); + break; + case CIL_DEVICETREECON: + cil_destroy_devicetreecon(*data); + break; + case CIL_POLICYCAP: + cil_destroy_policycap(*data); + break; + case CIL_DEFAULTUSER: + case CIL_DEFAULTROLE: + case CIL_DEFAULTTYPE: + cil_destroy_default(*data); + break; + case CIL_DEFAULTRANGE: + cil_destroy_defaultrange(*data); + break; + case CIL_HANDLEUNKNOWN: + cil_destroy_handleunknown(*data); + break; + case CIL_MLS: + cil_destroy_mls(*data); + break; + case CIL_SRC_INFO: + cil_destroy_src_info(*data); + break; + case CIL_OP: + case CIL_CONS_OPERAND: + break; + default: + cil_log(CIL_INFO, "Unknown data flavor: %d\n", flavor); + break; + } + + *data = NULL; +} + +int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_index) +{ + if (flavor < CIL_MIN_DECLARATIVE) { + return SEPOL_ERR; + } + + switch(flavor) { + case CIL_BLOCK: + *sym_index = CIL_SYM_BLOCKS; + break; + case CIL_MACRO: + *sym_index = CIL_SYM_BLOCKS; + break; + case CIL_OPTIONAL: + *sym_index = CIL_SYM_BLOCKS; + break; + case CIL_BOOL: + *sym_index = CIL_SYM_BOOLS; + break; + case CIL_TUNABLE: + *sym_index = CIL_SYM_TUNABLES; + break; + case CIL_PERM: + case CIL_MAP_PERM: + *sym_index = CIL_SYM_PERMS; + break; + case CIL_COMMON: + *sym_index = CIL_SYM_COMMONS; + break; + case CIL_CLASS: + case CIL_MAP_CLASS: + *sym_index = CIL_SYM_CLASSES; + break; + case CIL_CLASSPERMISSION: + case CIL_CLASSPERMISSIONSET: + *sym_index = CIL_SYM_CLASSPERMSETS; + break; + case CIL_USER: + case CIL_USERATTRIBUTE: + *sym_index = CIL_SYM_USERS; + break; + case CIL_ROLE: + case CIL_ROLEATTRIBUTE: + *sym_index = CIL_SYM_ROLES; + break; + case CIL_TYPE: + case CIL_TYPEALIAS: + case CIL_TYPEATTRIBUTE: + *sym_index = CIL_SYM_TYPES; + break; + case CIL_SENS: + case CIL_SENSALIAS: + *sym_index = CIL_SYM_SENS; + break; + case CIL_CAT: + case CIL_CATSET: + case CIL_CATALIAS: + *sym_index = CIL_SYM_CATS; + break; + case CIL_LEVEL: + *sym_index = CIL_SYM_LEVELS; + break; + case CIL_LEVELRANGE: + *sym_index = CIL_SYM_LEVELRANGES; + break; + case CIL_SID: + *sym_index = CIL_SYM_SIDS; + break; + case CIL_NAME: + *sym_index = CIL_SYM_NAMES; + break; + case CIL_CONTEXT: + *sym_index = CIL_SYM_CONTEXTS; + break; + case CIL_IPADDR: + *sym_index = CIL_SYM_IPADDRS; + break; + case CIL_POLICYCAP: + *sym_index = CIL_SYM_POLICYCAPS; + break; + case CIL_PERMISSIONX: + *sym_index = CIL_SYM_PERMX; + break; + default: + *sym_index = CIL_SYM_UNKNOWN; + cil_log(CIL_INFO, "Failed to find flavor: %d\n", flavor); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +const char * cil_node_to_string(struct cil_tree_node *node) +{ + switch (node->flavor) { + case CIL_NONE: + return ""; + case CIL_ROOT: + return CIL_KEY_ROOT; + case CIL_NODE: + return CIL_KEY_NODE; + case CIL_STRING: + return "string"; + case CIL_DATUM: + return ""; + case CIL_LIST: + return ""; + case CIL_LIST_ITEM: + return ""; + case CIL_PARAM: + return ""; + case CIL_ARGS: + return ""; + case CIL_BLOCK: + return CIL_KEY_BLOCK; + case CIL_BLOCKINHERIT: + return CIL_KEY_BLOCKINHERIT; + case CIL_BLOCKABSTRACT: + return CIL_KEY_BLOCKABSTRACT; + case CIL_IN: + return CIL_KEY_IN; + case CIL_MACRO: + return CIL_KEY_MACRO; + case CIL_CALL: + return CIL_KEY_CALL; + case CIL_OPTIONAL: + return CIL_KEY_OPTIONAL; + case CIL_BOOL: + return CIL_KEY_BOOL; + case CIL_BOOLEANIF: + return CIL_KEY_BOOLEANIF; + case CIL_TUNABLE: + return CIL_KEY_TUNABLE; + case CIL_TUNABLEIF: + return CIL_KEY_TUNABLEIF; + case CIL_CONDBLOCK: + switch (((struct cil_condblock*)node->data)->flavor) { + case CIL_CONDTRUE: + return CIL_KEY_CONDTRUE; + case CIL_CONDFALSE: + return CIL_KEY_CONDFALSE; + default: + break; + } + break; + case CIL_CONDTRUE: + return CIL_KEY_CONDTRUE; + case CIL_CONDFALSE: + return CIL_KEY_CONDFALSE; + case CIL_PERM: + return CIL_KEY_PERM; + case CIL_COMMON: + return CIL_KEY_COMMON; + case CIL_CLASS: + return CIL_KEY_CLASS; + case CIL_CLASSORDER: + return CIL_KEY_CLASSORDER; + case CIL_MAP_CLASS: + return CIL_KEY_MAP_CLASS; + case CIL_CLASSPERMISSION: + return CIL_KEY_CLASSPERMISSION; + case CIL_CLASSCOMMON: + return CIL_KEY_CLASSCOMMON; + case CIL_CLASSMAPPING: + return CIL_KEY_CLASSMAPPING; + case CIL_CLASSPERMISSIONSET: + return CIL_KEY_CLASSPERMISSIONSET; + case CIL_USER: + return CIL_KEY_USER; + case CIL_USERATTRIBUTE: + return CIL_KEY_USERATTRIBUTE; + case CIL_USERATTRIBUTESET: + return CIL_KEY_USERATTRIBUTESET; + case CIL_USERPREFIX: + return CIL_KEY_USERPREFIX; + case CIL_USERROLE: + return CIL_KEY_USERROLE; + case CIL_USERLEVEL: + return CIL_KEY_USERLEVEL; + case CIL_USERRANGE: + return CIL_KEY_USERRANGE; + case CIL_USERBOUNDS: + return CIL_KEY_USERBOUNDS; + case CIL_SELINUXUSER: + return CIL_KEY_SELINUXUSER; + case CIL_SELINUXUSERDEFAULT: + return CIL_KEY_SELINUXUSERDEFAULT; + case CIL_ROLE: + return CIL_KEY_ROLE; + case CIL_ROLEATTRIBUTE: + return CIL_KEY_ROLEATTRIBUTE; + case CIL_ROLEATTRIBUTESET: + return CIL_KEY_ROLEATTRIBUTESET; + case CIL_ROLETYPE: + return CIL_KEY_ROLETYPE; + case CIL_ROLEBOUNDS: + return CIL_KEY_ROLEBOUNDS; + case CIL_TYPE: + return CIL_KEY_TYPE; + case CIL_TYPEATTRIBUTE: + return CIL_KEY_TYPEATTRIBUTE; + case CIL_TYPEALIAS: + return CIL_KEY_TYPEALIAS; + case CIL_TYPEATTRIBUTESET: + return CIL_KEY_TYPEATTRIBUTESET; + case CIL_EXPANDTYPEATTRIBUTE: + return CIL_KEY_EXPANDTYPEATTRIBUTE; + case CIL_TYPEALIASACTUAL: + return CIL_KEY_TYPEALIASACTUAL; + case CIL_TYPEBOUNDS: + return CIL_KEY_TYPEBOUNDS; + case CIL_TYPEPERMISSIVE: + return CIL_KEY_TYPEPERMISSIVE; + case CIL_SENS: + return CIL_KEY_SENSITIVITY; + case CIL_SENSALIAS: + return CIL_KEY_SENSALIAS; + case CIL_SENSALIASACTUAL: + return CIL_KEY_SENSALIASACTUAL; + case CIL_SENSITIVITYORDER: + return CIL_KEY_SENSITIVITYORDER; + case CIL_SENSCAT: + return CIL_KEY_SENSCAT; + case CIL_CAT: + return CIL_KEY_CATEGORY; + case CIL_CATSET: + return CIL_KEY_CATSET; + case CIL_CATALIAS: + return CIL_KEY_CATALIAS; + case CIL_CATALIASACTUAL: + return CIL_KEY_CATALIASACTUAL; + case CIL_CATORDER: + return CIL_KEY_CATORDER; + case CIL_LEVEL: + return CIL_KEY_LEVEL; + case CIL_LEVELRANGE: + return CIL_KEY_LEVELRANGE; + case CIL_SID: + return CIL_KEY_SID; + case CIL_SIDORDER: + return CIL_KEY_SIDORDER; + case CIL_NAME: + return CIL_KEY_NAME; + case CIL_ROLEALLOW: + return CIL_KEY_ROLEALLOW; + case CIL_AVRULE: + switch (((struct cil_avrule *)node->data)->rule_kind) { + case CIL_AVRULE_ALLOWED: + return CIL_KEY_ALLOW; + case CIL_AVRULE_AUDITALLOW: + return CIL_KEY_AUDITALLOW; + case CIL_AVRULE_DONTAUDIT: + return CIL_KEY_DONTAUDIT; + case CIL_AVRULE_NEVERALLOW: + return CIL_KEY_NEVERALLOW; + default: + break; + } + break; + case CIL_AVRULEX: + switch (((struct cil_avrule *)node->data)->rule_kind) { + case CIL_AVRULE_ALLOWED: + return CIL_KEY_ALLOWX; + case CIL_AVRULE_AUDITALLOW: + return CIL_KEY_AUDITALLOWX; + case CIL_AVRULE_DONTAUDIT: + return CIL_KEY_DONTAUDITX; + case CIL_AVRULE_NEVERALLOW: + return CIL_KEY_NEVERALLOWX; + default: + break; + } + break; + case CIL_PERMISSIONX: + return CIL_KEY_PERMISSIONX; + case CIL_ROLETRANSITION: + return CIL_KEY_ROLETRANSITION; + case CIL_TYPE_RULE: + switch (((struct cil_type_rule *)node->data)->rule_kind) { + case CIL_TYPE_TRANSITION: + return CIL_KEY_TYPETRANSITION; + case CIL_TYPE_MEMBER: + return CIL_KEY_TYPEMEMBER; + case CIL_TYPE_CHANGE: + return CIL_KEY_TYPECHANGE; + default: + break; + } + break; + case CIL_NAMETYPETRANSITION: + return CIL_KEY_TYPETRANSITION; + case CIL_RANGETRANSITION: + return CIL_KEY_RANGETRANSITION; + case CIL_CONSTRAIN: + return CIL_KEY_CONSTRAIN; + case CIL_MLSCONSTRAIN: + return CIL_KEY_MLSCONSTRAIN; + case CIL_VALIDATETRANS: + return CIL_KEY_VALIDATETRANS; + case CIL_MLSVALIDATETRANS: + return CIL_KEY_MLSVALIDATETRANS; + case CIL_CONTEXT: + return CIL_KEY_CONTEXT; + case CIL_IPADDR: + return CIL_KEY_IPADDR; + case CIL_SIDCONTEXT: + return CIL_KEY_SIDCONTEXT; + case CIL_FSUSE: + return CIL_KEY_FSUSE; + case CIL_FILECON: + return CIL_KEY_FILECON; + case CIL_IBPKEYCON: + return CIL_KEY_IBPKEYCON; + case CIL_IBENDPORTCON: + return CIL_KEY_IBENDPORTCON; + case CIL_PORTCON: + return CIL_KEY_PORTCON; + case CIL_NODECON: + return CIL_KEY_NODECON; + case CIL_GENFSCON: + return CIL_KEY_GENFSCON; + case CIL_NETIFCON: + return CIL_KEY_NETIFCON; + case CIL_PIRQCON: + return CIL_KEY_PIRQCON; + case CIL_IOMEMCON: + return CIL_KEY_IOMEMCON; + case CIL_IOPORTCON: + return CIL_KEY_IOPORTCON; + case CIL_PCIDEVICECON: + return CIL_KEY_PCIDEVICECON; + case CIL_DEVICETREECON: + return CIL_KEY_DEVICETREECON; + case CIL_POLICYCAP: + return CIL_KEY_POLICYCAP; + case CIL_DEFAULTUSER: + return CIL_KEY_DEFAULTUSER; + case CIL_DEFAULTROLE: + return CIL_KEY_DEFAULTROLE; + case CIL_DEFAULTTYPE: + return CIL_KEY_DEFAULTTYPE; + case CIL_DEFAULTRANGE: + return CIL_KEY_DEFAULTRANGE; + case CIL_HANDLEUNKNOWN: + return CIL_KEY_HANDLEUNKNOWN; + case CIL_MLS: + return CIL_KEY_MLS; + case CIL_SRC_INFO: + return CIL_KEY_SRC_INFO; + case CIL_ALL: + return CIL_KEY_ALL; + case CIL_RANGE: + return CIL_KEY_RANGE; + case CIL_AND: + return CIL_KEY_AND; + case CIL_OR: + return CIL_KEY_OR; + case CIL_XOR: + return CIL_KEY_XOR; + case CIL_NOT: + return CIL_KEY_NOT; + case CIL_EQ: + return CIL_KEY_EQ; + case CIL_NEQ: + return CIL_KEY_NEQ; + case CIL_CONS_DOM: + return CIL_KEY_CONS_DOM; + case CIL_CONS_DOMBY: + return CIL_KEY_CONS_DOMBY; + case CIL_CONS_INCOMP: + return CIL_KEY_CONS_INCOMP; + case CIL_CONS_U1: + return CIL_KEY_CONS_U1; + case CIL_CONS_U2: + return CIL_KEY_CONS_U2; + case CIL_CONS_U3: + return CIL_KEY_CONS_U3; + case CIL_CONS_T1: + return CIL_KEY_CONS_T1; + case CIL_CONS_T2: + return CIL_KEY_CONS_T2; + case CIL_CONS_T3: + return CIL_KEY_CONS_T3; + case CIL_CONS_R1: + return CIL_KEY_CONS_R1; + case CIL_CONS_R2: + return CIL_KEY_CONS_R2; + case CIL_CONS_R3: + return CIL_KEY_CONS_R3; + case CIL_CONS_L1: + return CIL_KEY_CONS_L1; + case CIL_CONS_L2: + return CIL_KEY_CONS_L2; + case CIL_CONS_H1: + return CIL_KEY_CONS_H1; + case CIL_CONS_H2: + return CIL_KEY_CONS_H2; + + default: + break; + } + + return ""; +} + +int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size) +{ + int rc = SEPOL_ERR; + size_t str_len = 0; + int buf_pos = 0; + char *str_tmp = NULL; + struct cil_list_item *curr; + struct cil_userprefix *userprefix = NULL; + struct cil_user *user = NULL; + + *out = NULL; + + if (db->userprefixes->head == NULL) { + rc = SEPOL_OK; + *size = 0; + goto exit; + } + + cil_list_for_each(curr, db->userprefixes) { + userprefix = curr->data; + user = userprefix->user; + str_len += strlen("user ") + strlen(user->datum.fqn) + strlen(" prefix ") + strlen(userprefix->prefix_str) + 2; + } + + *size = str_len * sizeof(char); + str_len++; + str_tmp = cil_malloc(str_len * sizeof(char)); + *out = str_tmp; + + cil_list_for_each(curr, db->userprefixes) { + userprefix = curr->data; + user = userprefix->user; + + buf_pos = snprintf(str_tmp, str_len, "user %s prefix %s;\n", user->datum.fqn, + userprefix->prefix_str); + if (buf_pos < 0) { + free(str_tmp); + *size = 0; + *out = NULL; + goto exit; + } + str_len -= buf_pos; + str_tmp += buf_pos; + } + + rc = SEPOL_OK; +exit: + return rc; + +} + +static int cil_cats_to_ebitmap(struct cil_cats *cats, struct ebitmap* cats_ebitmap) +{ + int rc = SEPOL_ERR; + struct cil_list_item *i; + struct cil_list_item *j; + struct cil_cat* cat; + struct cil_catset *cs; + struct cil_tree_node *node; + + if (cats == NULL) { + rc = SEPOL_OK; + goto exit; + } + + cil_list_for_each(i, cats->datum_expr) { + node = NODE(i->data); + if (node->flavor == CIL_CATSET) { + cs = (struct cil_catset*)i->data; + cil_list_for_each(j, cs->cats->datum_expr) { + cat = (struct cil_cat*)j->data; + rc = ksu_ebitmap_set_bit(cats_ebitmap, cat->value, 1); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else { + cat = (struct cil_cat*)i->data; + rc = ksu_ebitmap_set_bit(cats_ebitmap, cat->value, 1); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_level_equals(struct cil_level *low, struct cil_level *high) +{ + int rc; + struct ebitmap elow; + struct ebitmap ehigh; + + if (strcmp(low->sens->datum.fqn, high->sens->datum.fqn)) { + rc = 0; + goto exit; + } + + ebitmap_init(&elow); + ebitmap_init(&ehigh); + + rc = cil_cats_to_ebitmap(low->cats, &elow); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_cats_to_ebitmap(high->cats, &ehigh); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = ksu_ebitmap_cmp(&elow, &ehigh); + ksu_ebitmap_destroy(&elow); + ksu_ebitmap_destroy(&ehigh); + +exit: + return rc; +} + +static int __cil_level_strlen(struct cil_level *lvl) +{ + struct cil_list_item *item; + struct cil_cats *cats = lvl->cats; + int str_len = 0; + char *str1 = NULL; + char *str2 = NULL; + int first = -1; + int last = -1; + + str_len += strlen(lvl->sens->datum.fqn); + + if (cats && cats->datum_expr != NULL) { + str_len++; /* initial ":" */ + cil_list_for_each(item, cats->datum_expr) { + struct cil_cat *cat = item->data; + if (first == -1) { + str1 = cat->datum.fqn; + first = cat->value; + last = first; + } else if (cat->value == last + 1) { + last++; + str2 = cat->datum.fqn; + } else { + if (first == last) { + str_len += strlen(str1) + strlen(cat->datum.fqn) + 1; + } else if (last == first + 1) { + str_len += strlen(str1) + strlen(str2) + strlen(cat->datum.fqn) + 2; + } else { + str_len += strlen(str1) + strlen(str2) + strlen(cat->datum.fqn) + 2; + } + first = -1; + last = -1; + if (item->next != NULL) { + str_len++; /* space for "," after */ + } + } + } + if (first != -1) { + if (first == last) { + str_len += strlen(str1); + } else if (last == first + 1) { + str_len += strlen(str1) + strlen(str2) + 1; + } else { + str_len += strlen(str1) + strlen(str2) + 1; + } + } + } + + return str_len; +} + +static int __cil_level_to_string(struct cil_level *lvl, char *out) +{ + struct cil_list_item *item; + struct cil_cats *cats = lvl->cats; + int buf_pos = 0; + char *str_tmp = out; + char *str1 = NULL; + char *str2 = NULL; + int first = -1; + int last = -1; + + buf_pos = sprintf(str_tmp, "%s", lvl->sens->datum.fqn); + str_tmp += buf_pos; + + if (cats && cats->datum_expr != NULL) { + buf_pos = sprintf(str_tmp, ":"); + str_tmp += buf_pos; + + cil_list_for_each(item, cats->datum_expr) { + struct cil_cat *cat = item->data; + if (first == -1) { + str1 = cat->datum.fqn; + first = cat->value; + last = first; + } else if (cat->value == last + 1) { + last++; + str2 = cat->datum.fqn; + } else { + if (first == last) { + buf_pos = sprintf(str_tmp, "%s,%s", str1, cat->datum.fqn); + str_tmp += buf_pos; + } else if (last == first + 1) { + buf_pos = sprintf(str_tmp, "%s,%s,%s", str1, str2, cat->datum.fqn); + str_tmp += buf_pos; + } else { + buf_pos = sprintf(str_tmp, "%s.%s,%s",str1, str2, cat->datum.fqn); + str_tmp += buf_pos; + } + first = -1; + last = -1; + if (item->next != NULL) { + buf_pos = sprintf(str_tmp, ","); + str_tmp += buf_pos; + } + } + } + if (first != -1) { + if (first == last) { + buf_pos = sprintf(str_tmp, "%s", str1); + str_tmp += buf_pos; + } else if (last == first + 1) { + buf_pos = sprintf(str_tmp, "%s,%s", str1, str2); + str_tmp += buf_pos; + } else { + buf_pos = sprintf(str_tmp, "%s.%s",str1, str2); + str_tmp += buf_pos; + } + } + } + + return str_tmp - out; +} + +int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size) +{ + size_t str_len = 0; + int buf_pos = 0; + char *str_tmp = NULL; + struct cil_list_item *curr; + + if (db->selinuxusers->head == NULL) { + *size = 0; + *out = NULL; + return SEPOL_OK; + } + + cil_list_for_each(curr, db->selinuxusers) { + struct cil_selinuxuser *selinuxuser = curr->data; + struct cil_user *user = selinuxuser->user; + + str_len += strlen(selinuxuser->name_str) + strlen(user->datum.fqn) + 1; + + if (db->mls == CIL_TRUE) { + struct cil_levelrange *range = selinuxuser->range; + str_len += __cil_level_strlen(range->low) + __cil_level_strlen(range->high) + 2; + } + + str_len++; + } + + *size = str_len * sizeof(char); + str_tmp = cil_malloc(*size+1); + *out = str_tmp; + + for(curr = db->selinuxusers->head; curr != NULL; curr = curr->next) { + struct cil_selinuxuser *selinuxuser = curr->data; + struct cil_user *user = selinuxuser->user; + + buf_pos = sprintf(str_tmp, "%s:%s", selinuxuser->name_str, user->datum.fqn); + str_tmp += buf_pos; + + if (db->mls == CIL_TRUE) { + struct cil_levelrange *range = selinuxuser->range; + buf_pos = sprintf(str_tmp, ":"); + str_tmp += buf_pos; + buf_pos = __cil_level_to_string(range->low, str_tmp); + str_tmp += buf_pos; + buf_pos = sprintf(str_tmp, "-"); + str_tmp += buf_pos; + buf_pos = __cil_level_to_string(range->high, str_tmp); + str_tmp += buf_pos; + } + + buf_pos = sprintf(str_tmp, "\n"); + str_tmp += buf_pos; + } + + return SEPOL_OK; +} + +int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size) +{ + uint32_t i = 0; + int buf_pos = 0; + size_t str_len = 0; + char *str_tmp = NULL; + struct cil_sort *filecons = db->filecon; + + for (i = 0; i < filecons->count; i++) { + struct cil_filecon *filecon = filecons->array[i]; + struct cil_context *ctx = filecon->context; + + str_len += strlen(filecon->path_str); + + if (filecon->type != CIL_FILECON_ANY) { + /* If a type is specified, + +2 for type string, +1 for tab */ + str_len += 3; + } + + if (ctx != NULL) { + struct cil_user *user = ctx->user; + struct cil_role *role = ctx->role; + struct cil_type *type = ctx->type; + + str_len += (strlen(user->datum.fqn) + strlen(role->datum.fqn) + strlen(type->datum.fqn) + 3); + + if (db->mls == CIL_TRUE) { + struct cil_levelrange *range = ctx->range; + if (cil_level_equals(range->low, range->high)) { + str_len += __cil_level_strlen(range->low) + 1; + } else { + str_len += __cil_level_strlen(range->low) + __cil_level_strlen(range->high) + 2; + } + } + } else { + str_len += strlen("\t<>"); + } + + str_len++; + } + + *size = str_len * sizeof(char); + str_tmp = cil_malloc(*size+1); + *out = str_tmp; + + for (i = 0; i < filecons->count; i++) { + struct cil_filecon *filecon = filecons->array[i]; + struct cil_context *ctx = filecon->context; + const char *str_type = NULL; + + buf_pos = sprintf(str_tmp, "%s", filecon->path_str); + str_tmp += buf_pos; + + switch(filecon->type) { + case CIL_FILECON_ANY: + str_type = ""; + break; + case CIL_FILECON_FILE: + str_type = "\t--"; + break; + case CIL_FILECON_DIR: + str_type = "\t-d"; + break; + case CIL_FILECON_CHAR: + str_type = "\t-c"; + break; + case CIL_FILECON_BLOCK: + str_type = "\t-b"; + break; + case CIL_FILECON_SOCKET: + str_type = "\t-s"; + break; + case CIL_FILECON_PIPE: + str_type = "\t-p"; + break; + case CIL_FILECON_SYMLINK: + str_type = "\t-l"; + break; + default: + str_type = ""; + break; + } + buf_pos = sprintf(str_tmp, "%s", str_type); + str_tmp += buf_pos; + + if (ctx != NULL) { + struct cil_user *user = ctx->user; + struct cil_role *role = ctx->role; + struct cil_type *type = ctx->type; + + buf_pos = sprintf(str_tmp, "\t%s:%s:%s", user->datum.fqn, role->datum.fqn, + type->datum.fqn); + str_tmp += buf_pos; + + if (db->mls == CIL_TRUE) { + struct cil_levelrange *range = ctx->range; + buf_pos = sprintf(str_tmp, ":"); + str_tmp += buf_pos; + buf_pos = __cil_level_to_string(range->low, str_tmp); + str_tmp += buf_pos; + + if (!cil_level_equals(range->low, range->high)) { + buf_pos = sprintf(str_tmp, "-"); + str_tmp += buf_pos; + buf_pos = __cil_level_to_string(range->high, str_tmp); + str_tmp += buf_pos; + } + } + } else { + buf_pos = sprintf(str_tmp, "\t<>"); + str_tmp += buf_pos; + } + + buf_pos = sprintf(str_tmp, "\n"); + str_tmp += buf_pos; + } + + return SEPOL_OK; +} + +void cil_set_disable_dontaudit(struct cil_db *db, int disable_dontaudit) +{ + db->disable_dontaudit = disable_dontaudit; +} + +void cil_set_disable_neverallow(struct cil_db *db, int disable_neverallow) +{ + db->disable_neverallow = disable_neverallow; +} + +void cil_set_attrs_expand_generated(struct cil_db *db, int attrs_expand_generated) +{ + db->attrs_expand_generated = attrs_expand_generated; +} + +void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_size) +{ + db->attrs_expand_size = attrs_expand_size; +} + +void cil_set_preserve_tunables(struct cil_db *db, int preserve_tunables) +{ + db->preserve_tunables = preserve_tunables; +} + +int cil_set_handle_unknown(struct cil_db *db, int handle_unknown) +{ + int rc = 0; + + switch (handle_unknown) { + case SEPOL_DENY_UNKNOWN: + case SEPOL_REJECT_UNKNOWN: + case SEPOL_ALLOW_UNKNOWN: + db->handle_unknown = handle_unknown; + break; + default: + cil_log(CIL_ERR, "Unknown value for handle-unknown: %i\n", handle_unknown); + rc = -1; + } + + return rc; +} + +void cil_set_mls(struct cil_db *db, int mls) +{ + db->mls = mls; +} + +void cil_set_multiple_decls(struct cil_db *db, int multiple_decls) +{ + db->multiple_decls = multiple_decls; +} + +void cil_set_qualified_names(struct cil_db *db, int qualified_names) +{ + db->qualified_names = qualified_names; +} + +void cil_set_target_platform(struct cil_db *db, int target_platform) +{ + db->target_platform = target_platform; +} + +void cil_set_policy_version(struct cil_db *db, int policy_version) +{ + db->policy_version = policy_version; +} + +void cil_symtab_array_init(symtab_t symtab[], const int symtab_sizes[CIL_SYM_NUM]) +{ + uint32_t i = 0; + for (i = 0; i < CIL_SYM_NUM; i++) { + cil_symtab_init(&symtab[i], symtab_sizes[i]); + } +} + +void cil_symtab_array_destroy(symtab_t symtab[]) +{ + int i = 0; + for (i = 0; i < CIL_SYM_NUM; i++) { + cil_symtab_destroy(&symtab[i]); + } +} + +void cil_destroy_ast_symtabs(struct cil_tree_node *current) +{ + while (current) { + switch (current->flavor) { + case CIL_BLOCK: + cil_symtab_array_destroy(((struct cil_block*)current->data)->symtab); + break; + case CIL_IN: + cil_symtab_array_destroy(((struct cil_in*)current->data)->symtab); + break; + case CIL_CLASS: + case CIL_COMMON: + case CIL_MAP_CLASS: + cil_symtab_destroy(&((struct cil_class*)current->data)->perms); + break; + case CIL_MACRO: + cil_symtab_array_destroy(((struct cil_macro*)current->data)->symtab); + break; + case CIL_CONDBLOCK: + cil_symtab_array_destroy(((struct cil_condblock*)current->data)->symtab); + break; + default: + break; + } + + if (current->cl_head) { + cil_destroy_ast_symtabs(current->cl_head); + } + + current = current->next; + } +} + +int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_sym_index sym_index) +{ + struct cil_tree_node *node = ast_node; + *symtab = NULL; + + if (sym_index == CIL_SYM_PERMS) { + /* Class statements are not blocks, so the passed node should be the class */ + if (node->flavor == CIL_CLASS || node->flavor == CIL_MAP_CLASS || + node->flavor == CIL_COMMON) { + *symtab = &((struct cil_class*)node->data)->perms; + return SEPOL_OK; + } + goto exit; + } + + if (sym_index < CIL_SYM_BLOCKS || sym_index >= CIL_SYM_NUM) { + cil_log(CIL_ERR, "Invalid symtab type\n"); + goto exit; + } + + while (node != NULL && *symtab == NULL) { + switch (node->flavor) { + case CIL_ROOT: + *symtab = &((struct cil_root *)node->data)->symtab[sym_index]; + break; + case CIL_BLOCK: + *symtab = &((struct cil_block*)node->data)->symtab[sym_index]; + break; + case CIL_MACRO: + *symtab = &((struct cil_macro*)node->data)->symtab[sym_index]; + break; + case CIL_IN: + /* In blocks only exist before resolving the AST */ + *symtab = &((struct cil_in*)node->data)->symtab[sym_index]; + break; + case CIL_CONDBLOCK: { + if (node->parent->flavor == CIL_TUNABLEIF) { + /* Cond blocks only exist before resolving the AST */ + *symtab = &((struct cil_condblock*)node->data)->symtab[sym_index]; + } else if (node->parent->flavor == CIL_BOOLEANIF) { + node = node->parent->parent; + } + break; + } + default: + node = node->parent; + } + } + + if (*symtab == NULL) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(ast_node, CIL_ERR, "Failed to get symtab from node"); + return SEPOL_ERR; +} + +int cil_string_to_uint32(const char *string, uint32_t *value, int base) +{ + unsigned long val; + char *end = NULL; + int rc = SEPOL_ERR; + + if (string == NULL || value == NULL) { + goto exit; + } + + errno = 0; + val = strtoul(string, &end, base); + if (errno != 0 || end == string || *end != '\0') { + rc = SEPOL_ERR; + goto exit; + } + + /* Ensure that the value fits a 32-bit integer without triggering -Wtype-limits */ +#if ULONG_MAX > UINT32_MAX + if (val > UINT32_MAX) { + rc = SEPOL_ERR; + goto exit; + } +#endif + + *value = val; + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to create uint32_t from string\n"); + return rc; +} + +int cil_string_to_uint64(const char *string, uint64_t *value, int base) +{ + char *end = NULL; + int rc = SEPOL_ERR; + + if (string == NULL || value == NULL) { + goto exit; + } + + errno = 0; + *value = strtoull(string, &end, base); + if (errno != 0 || end == string || *end != '\0') { + rc = SEPOL_ERR; + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to create uint64_t from string\n"); + return rc; +} + +void cil_sort_init(struct cil_sort **sort) +{ + *sort = cil_malloc(sizeof(**sort)); + + (*sort)->flavor = CIL_NONE; + (*sort)->count = 0; + (*sort)->index = 0; + (*sort)->array = NULL; +} + +void cil_sort_destroy(struct cil_sort **sort) +{ + (*sort)->flavor = CIL_NONE; + (*sort)->count = 0; + (*sort)->index = 0; + if ((*sort)->array != NULL) { + free((*sort)->array); + } + (*sort)->array = NULL; + + free(*sort); + *sort = NULL; +} + +void cil_netifcon_init(struct cil_netifcon **netifcon) +{ + *netifcon = cil_malloc(sizeof(**netifcon)); + + (*netifcon)->interface_str = NULL; + (*netifcon)->if_context_str = NULL; + (*netifcon)->if_context = NULL; + (*netifcon)->packet_context_str = NULL; + (*netifcon)->packet_context = NULL; + (*netifcon)->context_str = NULL; +} + +void cil_ibendportcon_init(struct cil_ibendportcon **ibendportcon) +{ + *ibendportcon = cil_malloc(sizeof(**ibendportcon)); + + (*ibendportcon)->dev_name_str = NULL; + (*ibendportcon)->port = 0; + (*ibendportcon)->context_str = NULL; + (*ibendportcon)->context = NULL; +} + +void cil_context_init(struct cil_context **context) +{ + *context = cil_malloc(sizeof(**context)); + + cil_symtab_datum_init(&(*context)->datum); + (*context)->user_str = NULL; + (*context)->user = NULL; + (*context)->role_str = NULL; + (*context)->role = NULL; + (*context)->type_str = NULL; + (*context)->type = NULL; + (*context)->range_str = NULL; + (*context)->range = NULL; +} + +void cil_level_init(struct cil_level **level) +{ + *level = cil_malloc(sizeof(**level)); + + cil_symtab_datum_init(&(*level)->datum); + (*level)->sens_str = NULL; + (*level)->sens = NULL; + (*level)->cats = NULL; +} + +void cil_levelrange_init(struct cil_levelrange **range) +{ + *range = cil_malloc(sizeof(**range)); + + cil_symtab_datum_init(&(*range)->datum); + (*range)->low_str = NULL; + (*range)->low = NULL; + (*range)->high_str = NULL; + (*range)->high = NULL; +} + +void cil_sens_init(struct cil_sens **sens) +{ + *sens = cil_malloc(sizeof(**sens)); + + cil_symtab_datum_init(&(*sens)->datum); + + (*sens)->cats_list = NULL; + + (*sens)->ordered = CIL_FALSE; +} + +void cil_block_init(struct cil_block **block) +{ + *block = cil_malloc(sizeof(**block)); + + cil_symtab_datum_init(&(*block)->datum); + + cil_symtab_array_init((*block)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_BLOCK]); + + (*block)->is_abstract = CIL_FALSE; + + (*block)->bi_nodes = NULL; +} + +void cil_blockinherit_init(struct cil_blockinherit **inherit) +{ + *inherit = cil_malloc(sizeof(**inherit)); + (*inherit)->block_str = NULL; + (*inherit)->block = NULL; +} + +void cil_blockabstract_init(struct cil_blockabstract **abstract) +{ + *abstract = cil_malloc(sizeof(**abstract)); + (*abstract)->block_str = NULL; +} + +void cil_in_init(struct cil_in **in) +{ + *in = cil_malloc(sizeof(**in)); + + cil_symtab_array_init((*in)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_IN]); + (*in)->is_after = CIL_FALSE; + (*in)->block_str = NULL; +} + +void cil_class_init(struct cil_class **class) +{ + *class = cil_malloc(sizeof(**class)); + + cil_symtab_datum_init(&(*class)->datum); + + cil_symtab_init(&(*class)->perms, CIL_CLASS_SYM_SIZE); + + (*class)->num_perms = 0; + (*class)->common = NULL; + (*class)->ordered = CIL_FALSE; +} + +void cil_classorder_init(struct cil_classorder **classorder) +{ + *classorder = cil_malloc(sizeof(**classorder)); + + (*classorder)->class_list_str = NULL; +} + +void cil_classcommon_init(struct cil_classcommon **classcommon) +{ + *classcommon = cil_malloc(sizeof(**classcommon)); + + (*classcommon)->class_str = NULL; + (*classcommon)->common_str = NULL; +} + +void cil_sid_init(struct cil_sid **sid) +{ + *sid = cil_malloc(sizeof(**sid)); + + cil_symtab_datum_init(&(*sid)->datum); + + (*sid)->ordered = CIL_FALSE; + (*sid)->context = NULL; +} + +void cil_sidcontext_init(struct cil_sidcontext **sidcontext) +{ + *sidcontext = cil_malloc(sizeof(**sidcontext)); + + (*sidcontext)->sid_str = NULL; + (*sidcontext)->context_str = NULL; + (*sidcontext)->context = NULL; +} + +void cil_sidorder_init(struct cil_sidorder **sidorder) +{ + *sidorder = cil_malloc(sizeof(**sidorder)); + + (*sidorder)->sid_list_str = NULL; +} + +void cil_userrole_init(struct cil_userrole **userrole) +{ + *userrole = cil_malloc(sizeof(**userrole)); + + (*userrole)->user_str = NULL; + (*userrole)->user = NULL; + (*userrole)->role_str = NULL; + (*userrole)->role = NULL; +} + +void cil_userprefix_init(struct cil_userprefix **userprefix) +{ + *userprefix = cil_malloc(sizeof(**userprefix)); + + (*userprefix)->user_str = NULL; + (*userprefix)->user = NULL; + (*userprefix)->prefix_str = NULL; +} + +void cil_selinuxuser_init(struct cil_selinuxuser **selinuxuser) +{ + *selinuxuser = cil_malloc(sizeof(**selinuxuser)); + + (*selinuxuser)->name_str = NULL; + (*selinuxuser)->user_str = NULL; + (*selinuxuser)->user = NULL; + (*selinuxuser)->range_str = NULL; + (*selinuxuser)->range = NULL; +} + +void cil_roletype_init(struct cil_roletype **roletype) +{ + *roletype = cil_malloc(sizeof(**roletype)); + + (*roletype)->role_str = NULL; + (*roletype)->role = NULL; + (*roletype)->type_str = NULL; + (*roletype)->type = NULL; +} + +void cil_roleattribute_init(struct cil_roleattribute **attr) +{ + *attr = cil_malloc(sizeof(**attr)); + + cil_symtab_datum_init(&(*attr)->datum); + + (*attr)->expr_list = NULL; + (*attr)->roles = NULL; +} + +void cil_roleattributeset_init(struct cil_roleattributeset **attrset) +{ + *attrset = cil_malloc(sizeof(**attrset)); + + (*attrset)->attr_str = NULL; + (*attrset)->str_expr = NULL; + (*attrset)->datum_expr = NULL; +} + +void cil_typeattribute_init(struct cil_typeattribute **attr) +{ + *attr = cil_malloc(sizeof(**attr)); + + cil_symtab_datum_init(&(*attr)->datum); + + (*attr)->expr_list = NULL; + (*attr)->types = NULL; + (*attr)->used = CIL_FALSE; + (*attr)->keep = CIL_FALSE; +} + +void cil_typeattributeset_init(struct cil_typeattributeset **attrset) +{ + *attrset = cil_malloc(sizeof(**attrset)); + + (*attrset)->attr_str = NULL; + (*attrset)->str_expr = NULL; + (*attrset)->datum_expr = NULL; +} + +void cil_expandtypeattribute_init(struct cil_expandtypeattribute **expandattr) +{ + *expandattr = cil_malloc(sizeof(**expandattr)); + + (*expandattr)->attr_strs = NULL; + (*expandattr)->attr_datums = NULL; + (*expandattr)->expand = 0; +} + +void cil_alias_init(struct cil_alias **alias) +{ + *alias = cil_malloc(sizeof(**alias)); + + (*alias)->actual = NULL; + + cil_symtab_datum_init(&(*alias)->datum); +} + +void cil_aliasactual_init(struct cil_aliasactual **aliasactual) +{ + *aliasactual = cil_malloc(sizeof(**aliasactual)); + + (*aliasactual)->alias_str = NULL; + (*aliasactual)->actual_str = NULL; +} + +void cil_typepermissive_init(struct cil_typepermissive **typeperm) +{ + *typeperm = cil_malloc(sizeof(**typeperm)); + + (*typeperm)->type_str = NULL; + (*typeperm)->type = NULL; +} + +void cil_name_init(struct cil_name **name) +{ + *name = cil_malloc(sizeof(**name)); + + cil_symtab_datum_init(&(*name)->datum); + (*name)->name_str = NULL; +} + +void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans) +{ + *nametypetrans = cil_malloc(sizeof(**nametypetrans)); + + (*nametypetrans)->src_str = NULL; + (*nametypetrans)->src = NULL; + (*nametypetrans)->tgt_str = NULL; + (*nametypetrans)->tgt = NULL; + (*nametypetrans)->obj_str = NULL; + (*nametypetrans)->obj = NULL; + (*nametypetrans)->name_str = NULL; + (*nametypetrans)->name = NULL; + (*nametypetrans)->result_str = NULL; + (*nametypetrans)->result = NULL; +} + +void cil_rangetransition_init(struct cil_rangetransition **rangetrans) +{ + *rangetrans = cil_malloc(sizeof(**rangetrans)); + + (*rangetrans)->src_str = NULL; + (*rangetrans)->src = NULL; + (*rangetrans)->exec_str = NULL; + (*rangetrans)->exec = NULL; + (*rangetrans)->obj_str = NULL; + (*rangetrans)->obj = NULL; + (*rangetrans)->range_str = NULL; + (*rangetrans)->range = NULL; +} + +void cil_bool_init(struct cil_bool **cilbool) +{ + *cilbool = cil_malloc(sizeof(**cilbool)); + + cil_symtab_datum_init(&(*cilbool)->datum); + (*cilbool)->value = 0; +} + +void cil_tunable_init(struct cil_tunable **ciltun) +{ + *ciltun = cil_malloc(sizeof(**ciltun)); + + cil_symtab_datum_init(&(*ciltun)->datum); + (*ciltun)->value = 0; +} + +void cil_condblock_init(struct cil_condblock **cb) +{ + *cb = cil_malloc(sizeof(**cb)); + + (*cb)->flavor = CIL_NONE; + cil_symtab_array_init((*cb)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_CONDBLOCK]); +} + +void cil_boolif_init(struct cil_booleanif **bif) +{ + *bif = cil_malloc(sizeof(**bif)); + + (*bif)->str_expr = NULL; + (*bif)->datum_expr = NULL; +} + +void cil_tunif_init(struct cil_tunableif **tif) +{ + *tif = cil_malloc(sizeof(**tif)); + + (*tif)->str_expr = NULL; + (*tif)->datum_expr = NULL; +} + +void cil_avrule_init(struct cil_avrule **avrule) +{ + *avrule = cil_malloc(sizeof(**avrule)); + + (*avrule)->is_extended = 0; + (*avrule)->rule_kind = CIL_NONE; + (*avrule)->src_str = NULL; + (*avrule)->src = NULL; + (*avrule)->tgt_str = NULL; + (*avrule)->tgt = NULL; + memset(&((*avrule)->perms), 0, sizeof((*avrule)->perms)); +} + +void cil_permissionx_init(struct cil_permissionx **permx) +{ + *permx = cil_malloc(sizeof(**permx)); + + cil_symtab_datum_init(&(*permx)->datum); + (*permx)->kind = CIL_NONE; + (*permx)->obj_str = NULL; + (*permx)->obj = NULL; + (*permx)->expr_str = NULL; + (*permx)->perms = NULL; +} + +void cil_type_rule_init(struct cil_type_rule **type_rule) +{ + *type_rule = cil_malloc(sizeof(**type_rule)); + + (*type_rule)->rule_kind = CIL_NONE; + (*type_rule)->src_str = NULL; + (*type_rule)->src = NULL; + (*type_rule)->tgt_str = NULL; + (*type_rule)->tgt = NULL; + (*type_rule)->obj_str = NULL; + (*type_rule)->obj = NULL; + (*type_rule)->result_str = NULL; + (*type_rule)->result = NULL; +} + +void cil_roletransition_init(struct cil_roletransition **role_trans) +{ + *role_trans = cil_malloc(sizeof(**role_trans)); + + (*role_trans)->src_str = NULL; + (*role_trans)->src = NULL; + (*role_trans)->tgt_str = NULL; + (*role_trans)->tgt = NULL; + (*role_trans)->obj_str = NULL; + (*role_trans)->obj = NULL; + (*role_trans)->result_str = NULL; + (*role_trans)->result = NULL; +} + +void cil_roleallow_init(struct cil_roleallow **roleallow) +{ + *roleallow = cil_malloc(sizeof(**roleallow)); + + (*roleallow)->src_str = NULL; + (*roleallow)->src = NULL; + (*roleallow)->tgt_str = NULL; + (*roleallow)->tgt = NULL; +} + +void cil_catset_init(struct cil_catset **catset) +{ + *catset = cil_malloc(sizeof(**catset)); + + cil_symtab_datum_init(&(*catset)->datum); + (*catset)->cats = NULL; +} + +void cil_senscat_init(struct cil_senscat **senscat) +{ + *senscat = cil_malloc(sizeof(**senscat)); + + (*senscat)->sens_str = NULL; + (*senscat)->cats = NULL; +} + +void cil_cats_init(struct cil_cats **cats) +{ + *cats = cil_malloc(sizeof(**cats)); + + (*cats)->evaluated = CIL_FALSE; + (*cats)->str_expr = NULL; + (*cats)->datum_expr = NULL; +} + +void cil_filecon_init(struct cil_filecon **filecon) +{ + *filecon = cil_malloc(sizeof(**filecon)); + + (*filecon)->path_str = NULL; + (*filecon)->type = CIL_FILECON_ANY; + (*filecon)->context_str = NULL; + (*filecon)->context = NULL; +} + +void cil_ibpkeycon_init(struct cil_ibpkeycon **ibpkeycon) +{ + *ibpkeycon = cil_malloc(sizeof(**ibpkeycon)); + + (*ibpkeycon)->subnet_prefix_str = NULL; + (*ibpkeycon)->pkey_low = 0; + (*ibpkeycon)->pkey_high = 0; + (*ibpkeycon)->context_str = NULL; + (*ibpkeycon)->context = NULL; +} + +void cil_portcon_init(struct cil_portcon **portcon) +{ + *portcon = cil_malloc(sizeof(**portcon)); + (*portcon)->proto = 0; + (*portcon)->port_low = 0; + (*portcon)->port_high = 0; + (*portcon)->context_str = NULL; + (*portcon)->context = NULL; +} + +void cil_nodecon_init(struct cil_nodecon **nodecon) +{ + *nodecon = cil_malloc(sizeof(**nodecon)); + + (*nodecon)->addr_str = NULL; + (*nodecon)->addr = NULL; + (*nodecon)->mask_str = NULL; + (*nodecon)->mask = NULL; + (*nodecon)->context_str = NULL; + (*nodecon)->context = NULL; +} + +void cil_genfscon_init(struct cil_genfscon **genfscon) +{ + *genfscon = cil_malloc(sizeof(**genfscon)); + + (*genfscon)->fs_str = NULL; + (*genfscon)->path_str = NULL; + (*genfscon)->file_type = CIL_FILECON_ANY; + (*genfscon)->context_str = NULL; + (*genfscon)->context = NULL; +} + +void cil_pirqcon_init(struct cil_pirqcon **pirqcon) +{ + *pirqcon = cil_malloc(sizeof(**pirqcon)); + + (*pirqcon)->pirq = 0; + (*pirqcon)->context_str = NULL; + (*pirqcon)->context = NULL; +} + +void cil_iomemcon_init(struct cil_iomemcon **iomemcon) +{ + *iomemcon = cil_malloc(sizeof(**iomemcon)); + + (*iomemcon)->iomem_low = 0; + (*iomemcon)->iomem_high = 0; + (*iomemcon)->context_str = NULL; + (*iomemcon)->context = NULL; +} + +void cil_ioportcon_init(struct cil_ioportcon **ioportcon) +{ + *ioportcon = cil_malloc(sizeof(**ioportcon)); + + (*ioportcon)->context_str = NULL; + (*ioportcon)->context = NULL; +} + +void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon) +{ + *pcidevicecon = cil_malloc(sizeof(**pcidevicecon)); + + (*pcidevicecon)->dev = 0; + (*pcidevicecon)->context_str = NULL; + (*pcidevicecon)->context = NULL; +} + +void cil_devicetreecon_init(struct cil_devicetreecon **dtcon) +{ + *dtcon = cil_malloc(sizeof(**dtcon)); + + (*dtcon)->path = NULL; + (*dtcon)->context_str = NULL; + (*dtcon)->context = NULL; +} + +void cil_fsuse_init(struct cil_fsuse **fsuse) +{ + *fsuse = cil_malloc(sizeof(**fsuse)); + + (*fsuse)->type = 0; + (*fsuse)->fs_str = NULL; + (*fsuse)->context_str = NULL; + (*fsuse)->context = NULL; +} + +void cil_constrain_init(struct cil_constrain **constrain) +{ + *constrain = cil_malloc(sizeof(**constrain)); + + (*constrain)->classperms = NULL; + (*constrain)->str_expr = NULL; + (*constrain)->datum_expr = NULL; +} + +void cil_validatetrans_init(struct cil_validatetrans **validtrans) +{ + *validtrans = cil_malloc(sizeof(**validtrans)); + + (*validtrans)->class_str = NULL; + (*validtrans)->class = NULL; + (*validtrans)->str_expr = NULL; + (*validtrans)->datum_expr = NULL; +} + +void cil_ipaddr_init(struct cil_ipaddr **ipaddr) +{ + *ipaddr = cil_malloc(sizeof(**ipaddr)); + + cil_symtab_datum_init(&(*ipaddr)->datum); + memset(&(*ipaddr)->ip, 0, sizeof((*ipaddr)->ip)); +} + +void cil_perm_init(struct cil_perm **perm) +{ + *perm = cil_malloc(sizeof(**perm)); + + cil_symtab_datum_init(&(*perm)->datum); + (*perm)->value = 0; + (*perm)->classperms = NULL; +} + +void cil_classpermission_init(struct cil_classpermission **cp) +{ + *cp = cil_malloc(sizeof(**cp)); + + cil_symtab_datum_init(&(*cp)->datum); + (*cp)->classperms = NULL; +} + +void cil_classpermissionset_init(struct cil_classpermissionset **cps) +{ + *cps = cil_malloc(sizeof(**cps)); + + (*cps)->set_str = NULL; + (*cps)->classperms = NULL; +} + +void cil_classperms_set_init(struct cil_classperms_set **cp_set) +{ + *cp_set = cil_malloc(sizeof(**cp_set)); + (*cp_set)->set_str = NULL; + (*cp_set)->set = NULL; +} + +void cil_classperms_init(struct cil_classperms **cp) +{ + *cp = cil_malloc(sizeof(**cp)); + (*cp)->class_str = NULL; + (*cp)->class = NULL; + (*cp)->perm_strs = NULL; + (*cp)->perms = NULL; +} + +void cil_classmapping_init(struct cil_classmapping **mapping) +{ + *mapping = cil_malloc(sizeof(**mapping)); + + (*mapping)->map_class_str = NULL; + (*mapping)->map_perm_str = NULL; + (*mapping)->classperms = NULL; +} + +void cil_user_init(struct cil_user **user) +{ + *user = cil_malloc(sizeof(**user)); + + cil_symtab_datum_init(&(*user)->datum); + (*user)->bounds = NULL; + (*user)->roles = NULL; + (*user)->dftlevel = NULL; + (*user)->range = NULL; + (*user)->value = 0; +} + +void cil_userattribute_init(struct cil_userattribute **attr) +{ + *attr = cil_malloc(sizeof(**attr)); + + cil_symtab_datum_init(&(*attr)->datum); + + (*attr)->expr_list = NULL; + (*attr)->users = NULL; +} + +void cil_userattributeset_init(struct cil_userattributeset **attrset) +{ + *attrset = cil_malloc(sizeof(**attrset)); + + (*attrset)->attr_str = NULL; + (*attrset)->str_expr = NULL; + (*attrset)->datum_expr = NULL; +} + +void cil_userlevel_init(struct cil_userlevel **usrlvl) +{ + *usrlvl = cil_malloc(sizeof(**usrlvl)); + + (*usrlvl)->user_str = NULL; + (*usrlvl)->level_str = NULL; + (*usrlvl)->level = NULL; +} + +void cil_userrange_init(struct cil_userrange **userrange) +{ + *userrange = cil_malloc(sizeof(**userrange)); + + (*userrange)->user_str = NULL; + (*userrange)->range_str = NULL; + (*userrange)->range = NULL; +} + +void cil_role_init(struct cil_role **role) +{ + *role = cil_malloc(sizeof(**role)); + + cil_symtab_datum_init(&(*role)->datum); + (*role)->bounds = NULL; + (*role)->types = NULL; + (*role)->value = 0; +} + +void cil_type_init(struct cil_type **type) +{ + *type = cil_malloc(sizeof(**type)); + + cil_symtab_datum_init(&(*type)->datum); + (*type)->bounds = NULL; + (*type)->value = 0; +} + +void cil_cat_init(struct cil_cat **cat) +{ + *cat = cil_malloc(sizeof(**cat)); + + cil_symtab_datum_init(&(*cat)->datum); + (*cat)->ordered = CIL_FALSE; + (*cat)->value = 0; +} + +void cil_catorder_init(struct cil_catorder **catorder) +{ + *catorder = cil_malloc(sizeof(**catorder)); + + (*catorder)->cat_list_str = NULL; +} + +void cil_sensorder_init(struct cil_sensorder **sensorder) +{ + *sensorder = cil_malloc(sizeof(**sensorder)); + + (*sensorder)->sens_list_str = NULL; +} + +void cil_args_init(struct cil_args **args) +{ + *args = cil_malloc(sizeof(**args)); + (*args)->arg_str = NULL; + (*args)->arg = NULL; + (*args)->param_str = NULL; + (*args)->flavor = CIL_NONE; +} + +void cil_call_init(struct cil_call **call) +{ + *call = cil_malloc(sizeof(**call)); + + (*call)->macro_str = NULL; + (*call)->macro = NULL; + (*call)->args_tree = NULL; + (*call)->args = NULL; + (*call)->copied = 0; +} + +void cil_optional_init(struct cil_optional **optional) +{ + *optional = cil_malloc(sizeof(**optional)); + cil_symtab_datum_init(&(*optional)->datum); +} + +void cil_param_init(struct cil_param **param) +{ + *param = cil_malloc(sizeof(**param)); + + (*param)->str = NULL; + (*param)->flavor = CIL_NONE; +} + +void cil_macro_init(struct cil_macro **macro) +{ + *macro = cil_malloc(sizeof(**macro)); + + cil_symtab_datum_init(&(*macro)->datum); + cil_symtab_array_init((*macro)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_MACRO]); + (*macro)->params = NULL; +} + +void cil_policycap_init(struct cil_policycap **policycap) +{ + *policycap = cil_malloc(sizeof(**policycap)); + + cil_symtab_datum_init(&(*policycap)->datum); +} + +void cil_bounds_init(struct cil_bounds **bounds) +{ + *bounds = cil_malloc(sizeof(**bounds)); + + (*bounds)->parent_str = NULL; + (*bounds)->child_str = NULL; +} + +void cil_default_init(struct cil_default **def) +{ + *def = cil_malloc(sizeof(**def)); + + (*def)->flavor = CIL_NONE; + (*def)->class_strs = NULL; + (*def)->class_datums = NULL; +} + +void cil_defaultrange_init(struct cil_defaultrange **def) +{ + *def = cil_malloc(sizeof(**def)); + + (*def)->class_strs = NULL; + (*def)->class_datums = NULL; +} + +void cil_handleunknown_init(struct cil_handleunknown **unk) +{ + *unk = cil_malloc(sizeof(**unk)); +} + +void cil_mls_init(struct cil_mls **mls) +{ + *mls = cil_malloc(sizeof(**mls)); + (*mls)->value = 0; +} + +void cil_src_info_init(struct cil_src_info **info) +{ + *info = cil_malloc(sizeof(**info)); + (*info)->kind = NULL; + (*info)->hll_line = 0; + (*info)->path = NULL; +} diff --git a/kernel/libsepol/cil/src/cil_binary.c b/kernel/libsepol/cil/src/cil_binary.c new file mode 100644 index 00000000..bc0cda13 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_binary.c @@ -0,0 +1,5217 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +#include +#include +#include +#include +#include +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_binary.h" +#include "cil_symtab.h" +#include "cil_find.h" +#include "cil_build_ast.h" + +#define ROLE_TRANS_TABLE_SIZE (1 << 10) +#define AVRULEX_TABLE_SIZE (1 << 10) +#define PERMS_PER_CLASS 32 + +struct cil_args_binary { + const struct cil_db *db; + policydb_t *pdb; + struct cil_list *neverallows; + int pass; + hashtab_t role_trans_table; + hashtab_t avrulex_ioctl_table; + void **type_value_to_cil; +}; + +struct cil_args_booleanif { + const struct cil_db *db; + policydb_t *pdb; + cond_node_t *cond_node; + enum cil_flavor cond_flavor; +}; + +static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user) +{ + *sepol_user = hashtab_search(pdb->p_users.table, datum->fqn); + if (*sepol_user == NULL) { + cil_log(CIL_INFO, "Failed to find user %s in sepol hashtab\n", datum->fqn); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __cil_get_sepol_role_datum(policydb_t *pdb, struct cil_symtab_datum *datum, role_datum_t **sepol_role) +{ + *sepol_role = hashtab_search(pdb->p_roles.table, datum->fqn); + if (*sepol_role == NULL) { + cil_log(CIL_INFO, "Failed to find role %s in sepol hashtab\n", datum->fqn); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __cil_get_sepol_type_datum(policydb_t *pdb, struct cil_symtab_datum *datum, type_datum_t **sepol_type) +{ + *sepol_type = hashtab_search(pdb->p_types.table, datum->fqn); + if (*sepol_type == NULL) { + cil_log(CIL_INFO, "Failed to find type %s in sepol hashtab\n", datum->fqn); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __cil_get_sepol_class_datum(policydb_t *pdb, struct cil_symtab_datum *datum, class_datum_t **sepol_class) +{ + *sepol_class = hashtab_search(pdb->p_classes.table, datum->fqn); + if (*sepol_class == NULL) { + cil_log(CIL_INFO, "Failed to find class %s in sepol hashtab\n", datum->fqn); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __cil_get_sepol_cat_datum(policydb_t *pdb, struct cil_symtab_datum *datum, cat_datum_t **sepol_cat) +{ + *sepol_cat = hashtab_search(pdb->p_cats.table, datum->fqn); + if (*sepol_cat == NULL) { + cil_log(CIL_INFO, "Failed to find category %s in sepol hashtab\n", datum->fqn); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum *datum, level_datum_t **sepol_level) +{ + *sepol_level = hashtab_search(pdb->p_levels.table, datum->fqn); + if (*sepol_level == NULL) { + cil_log(CIL_INFO, "Failed to find level %s in sepol hashtab\n", datum->fqn); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __cil_expand_user(struct cil_symtab_datum *datum, ebitmap_t *new) +{ + struct cil_tree_node *node = NODE(datum); + struct cil_user *user = NULL; + struct cil_userattribute *attr = NULL; + + if (node->flavor == CIL_USERATTRIBUTE) { + attr = (struct cil_userattribute *)datum; + if (ksu_ebitmap_cpy(new, attr->users)) { + cil_log(CIL_ERR, "Failed to copy user bits\n"); + goto exit; + } + } else { + user = (struct cil_user *)datum; + ebitmap_init(new); + if (ksu_ebitmap_set_bit(new, user->value, 1)) { + cil_log(CIL_ERR, "Failed to set user bit\n"); + ksu_ebitmap_destroy(new); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new) +{ + struct cil_tree_node *node = NODE(datum); + + if (node->flavor == CIL_ROLEATTRIBUTE) { + struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; + if (ksu_ebitmap_cpy(new, attr->roles)) { + cil_log(CIL_ERR, "Failed to copy role bits\n"); + goto exit; + } + } else { + struct cil_role *role = (struct cil_role *)datum; + ebitmap_init(new); + if (ksu_ebitmap_set_bit(new, role->value, 1)) { + cil_log(CIL_ERR, "Failed to set role bit\n"); + ksu_ebitmap_destroy(new); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new) +{ + struct cil_tree_node *node = NODE(datum); + + if (node->flavor == CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; + if (ksu_ebitmap_cpy(new, attr->types)) { + cil_log(CIL_ERR, "Failed to copy type bits\n"); + goto exit; + } + } else { + struct cil_type *type = (struct cil_type *)datum; + ebitmap_init(new); + if (ksu_ebitmap_set_bit(new, type->value, 1)) { + cil_log(CIL_ERR, "Failed to set type bit\n"); + ksu_ebitmap_destroy(new); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static ocontext_t *cil_add_ocontext(ocontext_t **head, ocontext_t **tail) +{ + ocontext_t *new = cil_malloc(sizeof(ocontext_t)); + memset(new, 0, sizeof(ocontext_t)); + if (*tail) { + (*tail)->next = new; + } else { + *head = new; + } + *tail = new; + + return new; +} + +int cil_common_to_policydb(policydb_t *pdb, struct cil_class *cil_common, common_datum_t **common_out) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + struct cil_tree_node *node = cil_common->datum.nodes->head->data; + struct cil_tree_node *cil_perm = node->cl_head; + common_datum_t *sepol_common = cil_malloc(sizeof(*sepol_common)); + memset(sepol_common, 0, sizeof(common_datum_t)); + + key = cil_strdup(cil_common->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_COMMONS, key, sepol_common, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + free(sepol_common); + goto exit; + } + sepol_common->s.value = value; + + rc = ksu_symtab_init(&sepol_common->permissions, PERM_SYMTAB_SIZE); + if (rc != SEPOL_OK) { + goto exit; + } + + while (cil_perm != NULL) { + struct cil_perm *curr = cil_perm->data; + perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm)); + memset(sepol_perm, 0, sizeof(perm_datum_t)); + + key = cil_strdup(curr->datum.fqn); + rc = hashtab_insert(sepol_common->permissions.table, key, sepol_perm); + if (rc != SEPOL_OK) { + free(sepol_perm); + goto exit; + } + sepol_perm->s.value = sepol_common->permissions.nprim + 1; + sepol_common->permissions.nprim++; + cil_perm = cil_perm->next; + } + + *common_out = sepol_common; + + return SEPOL_OK; + +exit: + free(key); + return rc; +} + +static int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr_class; + + cil_list_for_each(curr_class, db->classorder) { + struct cil_class *cil_class = curr_class->data; + uint32_t value = 0; + char *key = NULL; + int class_index; + struct cil_tree_node *curr; + common_datum_t *sepol_common = NULL; + class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class)); + memset(sepol_class, 0, sizeof(class_datum_t)); + + key = cil_strdup(cil_class->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_CLASSES, key, sepol_class, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + free(sepol_class); + free(key); + goto exit; + } + sepol_class->s.value = value; + class_index = value; + class_value_to_cil[class_index] = cil_class; + + rc = ksu_symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE); + if (rc != SEPOL_OK) { + goto exit; + } + + if (cil_class->common != NULL) { + int i; + struct cil_class *cil_common = cil_class->common; + + key = cil_class->common->datum.fqn; + sepol_common = hashtab_search(pdb->p_commons.table, key); + if (sepol_common == NULL) { + rc = cil_common_to_policydb(pdb, cil_common, &sepol_common); + if (rc != SEPOL_OK) { + goto exit; + } + } + sepol_class->comdatum = sepol_common; + sepol_class->comkey = cil_strdup(key); + sepol_class->permissions.nprim += sepol_common->permissions.nprim; + + for (curr = NODE(cil_class->common)->cl_head, i = 1; curr; curr = curr->next, i++) { + struct cil_perm *cil_perm = curr->data; + perm_value_to_cil[class_index][i] = cil_perm; + } + } + + for (curr = NODE(cil_class)->cl_head; curr; curr = curr->next) { + struct cil_perm *cil_perm = curr->data; + perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm)); + memset(sepol_perm, 0, sizeof(perm_datum_t)); + + key = cil_strdup(cil_perm->datum.fqn); + rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm); + if (rc != SEPOL_OK) { + free(sepol_perm); + free(key); + goto exit; + } + sepol_perm->s.value = sepol_class->permissions.nprim + 1; + sepol_class->permissions.nprim++; + perm_value_to_cil[class_index][sepol_perm->s.value] = cil_perm; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_role_to_policydb(policydb_t *pdb, struct cil_role *cil_role) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + role_datum_t *sepol_role = cil_malloc(sizeof(*sepol_role)); + role_datum_init(sepol_role); + + if (cil_role->datum.fqn == CIL_KEY_OBJECT_R) { + /* special case + * object_r defaults to 1 in libsepol symtab */ + rc = SEPOL_OK; + goto exit; + } + + key = cil_strdup(cil_role->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_ROLES, (hashtab_key_t)key, sepol_role, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + goto exit; + } + if (ksu_ebitmap_set_bit(&sepol_role->dominates, value - 1, 1)) { + cil_log(CIL_INFO, "Failed to set dominates bit for role\n"); + rc = SEPOL_ERR; + goto exit; + } + sepol_role->s.value = value; + return SEPOL_OK; + +exit: + free(key); + role_datum_destroy(sepol_role); + free(sepol_role); + return rc; +} + +static int cil_role_bounds_to_policydb(policydb_t *pdb, struct cil_role *cil_role) +{ + int rc = SEPOL_ERR; + role_datum_t *sepol_role = NULL; + role_datum_t *sepol_parent = NULL; + + if (cil_role->bounds) { + rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role), &sepol_role); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role->bounds), &sepol_parent); + if (rc != SEPOL_OK) goto exit; + + sepol_role->bounds = sepol_parent->s.value; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to insert role bounds for role %s\n", cil_role->datum.fqn); + return SEPOL_ERR; +} + +int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_role *role) +{ + int rc = SEPOL_ERR; + + if (role->types) { + role_datum_t *sepol_role = NULL; + type_datum_t *sepol_type = NULL; + ebitmap_node_t *tnode; + unsigned int i; + + rc = __cil_get_sepol_role_datum(pdb, DATUM(role), &sepol_role); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(role->types, tnode, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); + if (rc != SEPOL_OK) goto exit; + + if (ksu_ebitmap_set_bit(&sepol_role->types.types, sepol_type->s.value - 1, 1)) { + cil_log(CIL_INFO, "Failed to set type bit for role\n"); + rc = SEPOL_ERR; + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[]) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + type_datum_t *sepol_type = cil_malloc(sizeof(*sepol_type)); + type_datum_init(sepol_type); + + sepol_type->flavor = TYPE_TYPE; + + key = cil_strdup(cil_type->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_TYPES, key, sepol_type, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_type->s.value = value; + sepol_type->primary = 1; + + type_value_to_cil[value] = cil_type; + + return SEPOL_OK; + +exit: + free(key); + type_datum_destroy(sepol_type); + free(sepol_type); + return rc; +} + +static int cil_type_bounds_to_policydb(policydb_t *pdb, struct cil_type *cil_type) +{ + int rc = SEPOL_ERR; + type_datum_t *sepol_type = NULL; + type_datum_t *sepol_parent = NULL; + + if (cil_type->bounds) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type), &sepol_type); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type->bounds), &sepol_parent); + if (rc != SEPOL_OK) goto exit; + + sepol_type->bounds = sepol_parent->s.value; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to insert type bounds for type %s\n", cil_type->datum.fqn); + return SEPOL_ERR; +} + +int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) +{ + int rc = SEPOL_ERR; + char *key = NULL; + type_datum_t *sepol_type = NULL; + type_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias)); + type_datum_init(sepol_alias); + + rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_alias->actual), &sepol_type); + if (rc != SEPOL_OK) goto exit; + + sepol_alias->flavor = TYPE_TYPE; + + key = cil_strdup(cil_alias->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_TYPES, key, sepol_alias, SCOPE_DECL, 0, NULL); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_alias->s.value = sepol_type->s.value; + sepol_alias->primary = 0; + + return SEPOL_OK; + +exit: + free(key); + type_datum_destroy(sepol_alias); + free(sepol_alias); + return rc; +} + +int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm) +{ + int rc = SEPOL_ERR; + type_datum_t *sepol_type = NULL; + + rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_typeperm->type), &sepol_type); + if (rc != SEPOL_OK) goto exit; + + if (ksu_ebitmap_set_bit(&pdb->permissive_map, sepol_type->s.value, 1)) { + goto exit; + } + + return SEPOL_OK; + +exit: + type_datum_destroy(sepol_type); + free(sepol_type); + return rc; + +} + +int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[]) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + type_datum_t *sepol_attr = NULL; + + if (!cil_attr->keep) { + return SEPOL_OK; + } + + sepol_attr = cil_malloc(sizeof(*sepol_attr)); + type_datum_init(sepol_attr); + + sepol_attr->flavor = TYPE_ATTRIB; + + key = cil_strdup(cil_attr->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_TYPES, key, sepol_attr, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_attr->s.value = value; + sepol_attr->primary = 1; + + type_value_to_cil[value] = cil_attr; + + return SEPOL_OK; + +exit: + type_datum_destroy(sepol_attr); + free(sepol_attr); + return rc; +} + +static int __cil_typeattr_bitmap_init(policydb_t *pdb) +{ + int rc = SEPOL_ERR; + uint32_t i; + + pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); + pdb->attr_type_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); + + for (i = 0; i < pdb->p_types.nprim; i++) { + ebitmap_init(&pdb->type_attr_map[i]); + ebitmap_init(&pdb->attr_type_map[i]); + if (ksu_ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) { + rc = SEPOL_ERR; + goto exit; + } + if (pdb->type_val_to_struct[i] && pdb->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { + if (ksu_ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) { + rc = SEPOL_ERR; + goto exit; + } + } + + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct cil_typeattribute *cil_attr) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + type_datum_t *sepol_type = NULL; + ebitmap_node_t *tnode; + unsigned int i; + + if (!cil_attr->keep) { + return SEPOL_OK; + } + + if (pdb->type_attr_map == NULL) { + rc = __cil_typeattr_bitmap_init(pdb); + if (rc != SEPOL_OK) { + goto exit; + } + } + + rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_attr), &sepol_type); + if (rc != SEPOL_OK) goto exit; + + value = sepol_type->s.value; + + ebitmap_for_each_positive_bit(cil_attr->types, tnode, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); + if (rc != SEPOL_OK) goto exit; + + ksu_ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1); + ksu_ebitmap_set_bit(&pdb->attr_type_map[value - 1], sepol_type->s.value - 1, 1); + } + + rc = SEPOL_OK; +exit: + return rc; +} + +int cil_policycap_to_policydb(policydb_t *pdb, struct cil_policycap *cil_polcap) +{ + int rc = SEPOL_ERR; + int capnum; + + capnum = sepol_polcap_getnum(cil_polcap->datum.fqn); + if (capnum == -1) { + goto exit; + } + + if (ksu_ebitmap_set_bit(&pdb->policycaps, capnum, 1)) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + user_datum_t *sepol_user = cil_malloc(sizeof(*sepol_user)); + user_datum_init(sepol_user); + + key = cil_strdup(cil_user->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_USERS, key, sepol_user, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_user->s.value = value; + + return SEPOL_OK; + +exit: + free(key); + user_datum_destroy(sepol_user); + free(sepol_user); + return rc; +} + +static int cil_user_bounds_to_policydb(policydb_t *pdb, struct cil_user *cil_user) +{ + int rc = SEPOL_ERR; + user_datum_t *sepol_user = NULL; + user_datum_t *sepol_parent = NULL; + + if (cil_user->bounds) { + rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user->bounds), &sepol_parent); + if (rc != SEPOL_OK) goto exit; + + sepol_user->bounds = sepol_parent->s.value; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to insert user bounds for user %s\n", cil_user->datum.fqn); + return SEPOL_ERR; +} + +int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user) +{ + int rc = SEPOL_ERR; + user_datum_t *sepol_user = NULL; + role_datum_t *sepol_role = NULL; + ebitmap_node_t *rnode = NULL; + unsigned int i; + + if (user->roles) { + rc = __cil_get_sepol_user_datum(pdb, DATUM(user), &sepol_user); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_positive_bit(user->roles, rnode, i) { + rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role); + if (rc != SEPOL_OK) { + goto exit; + } + + if (sepol_role->s.value == 1) { + // role is object_r, ignore it since it is implicitly associated + // with all users + continue; + } + + if (ksu_ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) { + cil_log(CIL_INFO, "Failed to set role bit for user\n"); + rc = SEPOL_ERR; + goto exit; + } + } + } + + rc = SEPOL_OK; + +exit: + return rc; +} + +int cil_bool_to_policydb(policydb_t *pdb, struct cil_bool *cil_bool) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + cond_bool_datum_t *sepol_bool = cil_malloc(sizeof(*sepol_bool)); + memset(sepol_bool, 0, sizeof(cond_bool_datum_t)); + + key = cil_strdup(cil_bool->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_BOOLS, key, sepol_bool, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_bool->s.value = value; + sepol_bool->state = cil_bool->value; + + return SEPOL_OK; + +exit: + free(key); + free(sepol_bool); + return rc; +} + +int cil_catorder_to_policydb(policydb_t *pdb, const struct cil_db *db) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + struct cil_list_item *curr_cat; + struct cil_cat *cil_cat = NULL; + cat_datum_t *sepol_cat = NULL; + + cil_list_for_each(curr_cat, db->catorder) { + cil_cat = curr_cat->data; + sepol_cat = cil_malloc(sizeof(*sepol_cat)); + cat_datum_init(sepol_cat); + + key = cil_strdup(cil_cat->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_CATS, key, sepol_cat, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_cat->s.value = value; + } + + return SEPOL_OK; + +exit: + free(key); + cat_datum_destroy(sepol_cat); + free(sepol_cat); + return rc; +} + +int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) +{ + int rc = SEPOL_ERR; + char *key = NULL; + cat_datum_t *sepol_cat; + cat_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_cat)); + cat_datum_init(sepol_alias); + + rc = __cil_get_sepol_cat_datum(pdb, DATUM(cil_alias->actual), &sepol_cat); + if (rc != SEPOL_OK) goto exit; + + key = cil_strdup(cil_alias->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_alias->s.value = sepol_cat->s.value; + sepol_alias->isalias = 1; + + return SEPOL_OK; + +exit: + free(key); + cat_datum_destroy(sepol_alias); + free(sepol_alias); + return rc; +} + +int cil_sensitivityorder_to_policydb(policydb_t *pdb, const struct cil_db *db) +{ + int rc = SEPOL_ERR; + uint32_t value = 0; + char *key = NULL; + struct cil_list_item *curr; + struct cil_sens *cil_sens = NULL; + level_datum_t *sepol_level = NULL; + mls_level_t *mls_level = NULL; + + cil_list_for_each(curr, db->sensitivityorder) { + cil_sens = curr->data; + sepol_level = cil_malloc(sizeof(*sepol_level)); + mls_level = cil_malloc(sizeof(*mls_level)); + level_datum_init(sepol_level); + mls_level_init(mls_level); + + key = cil_strdup(cil_sens->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_LEVELS, key, sepol_level, SCOPE_DECL, 0, &value); + if (rc != SEPOL_OK) { + goto exit; + } + mls_level->sens = value; + sepol_level->level = mls_level; + } + + return SEPOL_OK; + +exit: + level_datum_destroy(sepol_level); + mls_level_destroy(mls_level); + free(sepol_level); + free(mls_level); + free(key); + return rc; +} + +static int cil_sensalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) +{ + int rc = SEPOL_ERR; + char *key = NULL; + mls_level_t *mls_level = NULL; + level_datum_t *sepol_level = NULL; + level_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias)); + level_datum_init(sepol_alias); + + rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_alias->actual), &sepol_level); + if (rc != SEPOL_OK) goto exit; + + key = cil_strdup(cil_alias->datum.fqn); + rc = ksu_symtab_insert(pdb, SYM_LEVELS, key, sepol_alias, SCOPE_DECL, 0, NULL); + if (rc != SEPOL_OK) { + goto exit; + } + + mls_level = cil_malloc(sizeof(*mls_level)); + mls_level_init(mls_level); + + rc = mls_level_cpy(mls_level, sepol_level->level); + if (rc != SEPOL_OK) { + goto exit; + } + sepol_alias->level = mls_level; + sepol_alias->defined = 1; + sepol_alias->isalias = 1; + + return SEPOL_OK; + +exit: + level_datum_destroy(sepol_alias); + free(sepol_alias); + free(key); + return rc; +} + +static int __cil_cond_insert_rule(avtab_t *avtab, avtab_key_t *avtab_key, avtab_datum_t *avtab_datum, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_OK; + avtab_ptr_t avtab_ptr = NULL; + cond_av_list_t *cond_list = NULL; + + avtab_ptr = ksu_avtab_insert_nonunique(avtab, avtab_key, avtab_datum); + if (!avtab_ptr) { + rc = SEPOL_ERR; + goto exit; + } + + // parse_context needs to be non-NULL for conditional rules to be + // written to the binary. it is normally used for finding duplicates, + // but cil checks that earlier, so we don't use it. it just needs to be + // set + avtab_ptr->parse_context = (void*)1; + + cond_list = cil_malloc(sizeof(cond_av_list_t)); + memset(cond_list, 0, sizeof(cond_av_list_t)); + + cond_list->node = avtab_ptr; + + if (cond_flavor == CIL_CONDTRUE) { + cond_list->next = cond_node->true_list; + cond_node->true_list = cond_list; + } else { + cond_list->next = cond_node->false_list; + cond_node->false_list = cond_list; + } + +exit: + return rc; +} + +static avtab_datum_t *cil_cond_av_list_search(avtab_key_t *key, cond_av_list_t *cond_list) +{ + cond_av_list_t *cur_av; + + for (cur_av = cond_list; cur_av != NULL; cur_av = cur_av->next) { + if (cur_av->node->key.source_type == key->source_type && + cur_av->node->key.target_type == key->target_type && + cur_av->node->key.target_class == key->target_class && + (cur_av->node->key.specified & key->specified)) + + return &cur_av->node->datum; + + } + return NULL; +} + +static int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_OK; + avtab_key_t avtab_key; + avtab_datum_t avtab_datum; + avtab_ptr_t existing; + + avtab_key.source_type = src; + avtab_key.target_type = tgt; + avtab_key.target_class = obj; + + switch (kind) { + case CIL_TYPE_TRANSITION: + avtab_key.specified = AVTAB_TRANSITION; + break; + case CIL_TYPE_CHANGE: + avtab_key.specified = AVTAB_CHANGE; + break; + case CIL_TYPE_MEMBER: + avtab_key.specified = AVTAB_MEMBER; + break; + default: + rc = SEPOL_ERR; + goto exit; + } + + avtab_datum.data = res; + + existing = ksu_avtab_search_node(&pdb->te_avtab, &avtab_key); + if (existing) { + /* Don't add duplicate type rule and warn if they conflict. + * A warning should have been previously given if there is a + * non-duplicate rule using the same key. + */ + if (existing->datum.data != res) { + cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s), existing=%s\n", + pdb->p_type_val_to_name[src - 1], + pdb->p_type_val_to_name[tgt - 1], + pdb->p_class_val_to_name[obj - 1], + pdb->p_type_val_to_name[res - 1], + pdb->p_type_val_to_name[existing->datum.data - 1]); + cil_log(CIL_ERR, "Expanded from type rule (scontext=%s tcontext=%s tclass=%s result=%s)\n", + cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str); + rc = SEPOL_ERR; + } + goto exit; + } + + if (!cond_node) { + rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum); + } else { + existing = ksu_avtab_search_node(&pdb->te_cond_avtab, &avtab_key); + if (existing) { + cond_av_list_t *this_list; + cond_av_list_t *other_list; + avtab_datum_t *search_datum; + + if (cond_flavor == CIL_CONDTRUE) { + this_list = cond_node->true_list; + other_list = cond_node->false_list; + } else { + this_list = cond_node->false_list; + other_list = cond_node->true_list; + } + + search_datum = cil_cond_av_list_search(&avtab_key, other_list); + if (search_datum == NULL) { + if (existing->datum.data != res) { + cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s), existing=%s\n", + pdb->p_type_val_to_name[src - 1], + pdb->p_type_val_to_name[tgt - 1], + pdb->p_class_val_to_name[obj - 1], + pdb->p_type_val_to_name[res - 1], + pdb->p_type_val_to_name[existing->datum.data - 1]); + cil_log(CIL_ERR, "Expanded from type rule (scontext=%s tcontext=%s tclass=%s result=%s)\n", + cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str); + rc = SEPOL_ERR; + goto exit; + } + + search_datum = cil_cond_av_list_search(&avtab_key, this_list); + if (search_datum) { + goto exit; + } + } + } + rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor); + } + +exit: + return rc; +} + +static int __cil_type_rule_to_avtab_helper(policydb_t *pdb, + type_datum_t *sepol_src, + type_datum_t *sepol_tgt, + struct cil_list *class_list, + type_datum_t *sepol_result, + struct cil_type_rule *cil_rule, + cond_node_t *cond_node, + enum cil_flavor cond_flavor) +{ + int rc; + class_datum_t *sepol_obj = NULL; + struct cil_list_item *c; + + cil_list_for_each(c, class_list) { + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); + if (rc != SEPOL_OK) return rc; + + rc = __cil_insert_type_rule( + pdb, cil_rule->rule_kind, sepol_src->s.value, + sepol_tgt->s.value, sepol_obj->s.value, + sepol_result->s.value, cil_rule, cond_node, cond_flavor + ); + if (rc != SEPOL_OK) return rc; + } + return SEPOL_OK; +} + +static int __cil_type_rule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_ERR; + struct cil_symtab_datum *src = NULL; + struct cil_symtab_datum *tgt = NULL; + type_datum_t *sepol_src = NULL; + type_datum_t *sepol_tgt = NULL; + struct cil_list *class_list = NULL; + type_datum_t *sepol_result = NULL; + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *node1, *node2; + unsigned int i, j; + + ebitmap_init(&src_bitmap); + ebitmap_init(&tgt_bitmap); + + src = cil_rule->src; + tgt = cil_rule->tgt; + + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) goto exit; + + class_list = cil_expand_class(cil_rule->obj); + + rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_rule->result), &sepol_result); + if (rc != SEPOL_OK) goto exit; + + if (tgt->fqn == CIL_KEY_SELF) { + ebitmap_for_each_positive_bit(&src_bitmap, node1, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_type_rule_to_avtab_helper( + pdb, sepol_src, sepol_src, class_list, + sepol_result, cil_rule, cond_node, cond_flavor + ); + if (rc != SEPOL_OK) goto exit; + } + } else { + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&src_bitmap, node1, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_type_rule_to_avtab_helper( + pdb, sepol_src, sepol_tgt, class_list, + sepol_result, cil_rule, cond_node, + cond_flavor + ); + if (rc != SEPOL_OK) goto exit; + } + } + } + + rc = SEPOL_OK; + +exit: + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + cil_list_destroy(&class_list, CIL_FALSE); + return rc; +} + +int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule) +{ + return __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE); +} + +static int __cil_typetransition_to_avtab_helper(policydb_t *pdb, + type_datum_t *sepol_src, + type_datum_t *sepol_tgt, + struct cil_list *class_list, + char *name, + type_datum_t *sepol_result) +{ + int rc; + class_datum_t *sepol_obj = NULL; + uint32_t otype; + struct cil_list_item *c; + + cil_list_for_each(c, class_list) { + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); + if (rc != SEPOL_OK) return rc; + + rc = policydb_filetrans_insert( + pdb, sepol_src->s.value, sepol_tgt->s.value, + sepol_obj->s.value, name, NULL, + sepol_result->s.value, &otype + ); + if (rc != SEPOL_OK) { + if (rc == SEPOL_EEXIST) { + if (sepol_result->s.value!= otype) { + cil_log(CIL_ERR, "Conflicting name type transition rules\n"); + } else { + rc = SEPOL_OK; + } + } else { + cil_log(CIL_ERR, "Out of memory\n"); + } + if (rc != SEPOL_OK) { + return rc; + } + } + } + return SEPOL_OK; +} + +static int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_ERR; + struct cil_symtab_datum *src = NULL; + struct cil_symtab_datum *tgt = NULL; + type_datum_t *sepol_src = NULL; + type_datum_t *sepol_tgt = NULL; + struct cil_list *class_list = NULL; + type_datum_t *sepol_result = NULL; + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *node1, *node2; + unsigned int i, j; + char *name = DATUM(typetrans->name)->name; + + if (name == CIL_KEY_STAR) { + struct cil_type_rule trans; + trans.rule_kind = CIL_TYPE_TRANSITION; + trans.src = typetrans->src; + trans.tgt = typetrans->tgt; + trans.obj = typetrans->obj; + trans.result = typetrans->result; + trans.src_str = typetrans->src_str; + trans.tgt_str = typetrans->tgt_str; + trans.obj_str = typetrans->obj_str; + trans.result_str = typetrans->result_str; + return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor); + } + + ebitmap_init(&src_bitmap); + ebitmap_init(&tgt_bitmap); + + src = typetrans->src; + tgt = typetrans->tgt; + + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) goto exit; + + class_list = cil_expand_class(typetrans->obj); + + rc = __cil_get_sepol_type_datum(pdb, DATUM(typetrans->result), &sepol_result); + if (rc != SEPOL_OK) goto exit; + + if (tgt->fqn == CIL_KEY_SELF) { + ebitmap_for_each_positive_bit(&src_bitmap, node1, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_typetransition_to_avtab_helper( + pdb, sepol_src, sepol_src, class_list, + name, sepol_result + ); + if (rc != SEPOL_OK) goto exit; + } + } else { + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&src_bitmap, node1, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_typetransition_to_avtab_helper( + pdb, sepol_src, sepol_tgt, class_list, + name, sepol_result + ); + if (rc != SEPOL_OK) goto exit; + } + } + } + + rc = SEPOL_OK; + +exit: + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + cil_list_destroy(&class_list, CIL_FALSE); + return rc; +} + +int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans) +{ + return __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE); +} + +static int __perm_str_to_datum(char *perm_str, class_datum_t *sepol_class, uint32_t *datum) +{ + int rc; + perm_datum_t *sepol_perm; + common_datum_t *sepol_common; + + sepol_perm = hashtab_search(sepol_class->permissions.table, perm_str); + if (sepol_perm == NULL) { + sepol_common = sepol_class->comdatum; + sepol_perm = hashtab_search(sepol_common->permissions.table, perm_str); + if (sepol_perm == NULL) { + cil_log(CIL_ERR, "Failed to find datum for perm %s\n", perm_str); + rc = SEPOL_ERR; + goto exit; + } + } + *datum |= UINT32_C(1) << (sepol_perm->s.value - 1); + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_perms_to_datum(struct cil_list *perms, class_datum_t *sepol_class, uint32_t *datum) +{ + int rc = SEPOL_ERR; + char *key = NULL; + struct cil_list_item *curr_perm; + struct cil_perm *cil_perm; + uint32_t data = 0; + + cil_list_for_each(curr_perm, perms) { + cil_perm = curr_perm->data; + key = cil_perm->datum.fqn; + + rc = __perm_str_to_datum(key, sepol_class, &data); + if (rc != SEPOL_OK) { + goto exit; + } + } + + *datum = data; + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_insert_avrule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t data, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_OK; + avtab_key_t avtab_key; + avtab_datum_t avtab_datum; + avtab_datum_t *avtab_dup = NULL; + + avtab_key.source_type = src; + avtab_key.target_type = tgt; + avtab_key.target_class = obj; + + switch (kind) { + case CIL_AVRULE_ALLOWED: + avtab_key.specified = AVTAB_ALLOWED; + break; + case CIL_AVRULE_AUDITALLOW: + avtab_key.specified = AVTAB_AUDITALLOW; + break; + case CIL_AVRULE_DONTAUDIT: + avtab_key.specified = AVTAB_AUDITDENY; + break; + default: + rc = SEPOL_ERR; + goto exit; + break; + } + + if (!cond_node) { + avtab_dup = ksu_avtab_search(&pdb->te_avtab, &avtab_key); + if (!avtab_dup) { + avtab_datum.data = data; + rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum); + } else { + if (kind == CIL_AVRULE_DONTAUDIT) + avtab_dup->data &= data; + else + avtab_dup->data |= data; + } + } else { + avtab_datum.data = data; + rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor); + } + +exit: + return rc; +} + +static int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_ERR; + type_datum_t *sepol_src = NULL; + type_datum_t *sepol_tgt = NULL; + class_datum_t *sepol_class = NULL; + uint32_t data = 0; + + rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_perms_to_datum(cp->perms, sepol_class, &data); + if (rc != SEPOL_OK) goto exit; + + if (data == 0) { + /* No permissions, so don't insert rule. Maybe should return an error? */ + return SEPOL_OK; + } + + if (kind == CIL_AVRULE_DONTAUDIT) { + data = ~data; + } + + rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + + +static int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + + cil_list_for_each(curr, classperms) { + if (curr->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = curr->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + goto exit; + } + } else { /* MAP */ + struct cil_list_item *i = NULL; + cil_list_for_each(i, cp->perms) { + struct cil_perm *cmp = i->data; + rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_should_expand_attribute( const struct cil_db *db, struct cil_symtab_datum *datum) +{ + struct cil_tree_node *node; + struct cil_typeattribute *attr; + + node = NODE(datum); + + if (node->flavor != CIL_TYPEATTRIBUTE) { + return CIL_FALSE; + } + + attr = (struct cil_typeattribute *)datum; + + return !attr->keep || (ebitmap_cardinality(attr->types) < db->attrs_expand_size); +} + +static int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor) +{ + int rc = SEPOL_ERR; + uint16_t kind = cil_avrule->rule_kind; + struct cil_symtab_datum *src = NULL; + struct cil_symtab_datum *tgt = NULL; + struct cil_list *classperms = cil_avrule->perms.classperms; + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *snode, *tnode; + unsigned int s,t; + + if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) { + // Do not add dontaudit rules to binary + rc = SEPOL_OK; + goto exit; + } + + src = cil_avrule->src; + tgt = cil_avrule->tgt; + + if (tgt->fqn == CIL_KEY_SELF) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { + src = DATUM(db->val_to_type[s]); + rc = __cil_avrule_expand(pdb, kind, src, src, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&src_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&src_bitmap); + } else { + int expand_src = __cil_should_expand_attribute(db, src); + int expand_tgt = __cil_should_expand_attribute(db, tgt); + if (!expand_src && !expand_tgt) { + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + goto exit; + } + } else if (expand_src && expand_tgt) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&src_bitmap); + goto exit; + } + + ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { + src = DATUM(db->val_to_type[s]); + ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) { + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + } + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + } else if (expand_src) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { + src = DATUM(db->val_to_type[s]); + + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&src_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&src_bitmap); + } else { /* expand_tgt */ + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) { + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&tgt_bitmap); + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule) +{ + return __cil_avrule_to_avtab(pdb, db, cil_avrule, NULL, CIL_FALSE); +} + +// Copied from checkpolicy/policy_define.c + +/* index of the u32 containing the permission */ +#define XPERM_IDX(x) (x >> 5) +/* set bits 0 through x-1 within the u32 */ +#define XPERM_SETBITS(x) ((UINT32_C(1) << (x & 0x1f)) - 1) +/* low value for this u32 */ +#define XPERM_LOW(x) (x << 5) +/* high value for this u32 */ +#define XPERM_HIGH(x) (((x + 1) << 5) - 1) +static void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avtab_extended_perms *xperms) +{ + unsigned int i; + uint16_t h = high + 1; + /* for each u32 that this low-high range touches, set driver permissions */ + for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) { + /* set all bits in u32 */ + if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) + xperms->perms[i] |= ~0U; + /* set low bits */ + else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i))) + xperms->perms[i] |= XPERM_SETBITS(h); + /* set high bits */ + else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) + xperms->perms[i] |= ~0U - XPERM_SETBITS(low); + /* set middle bits */ + else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i))) + xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low); + } +} + + +#define IOC_DRIV(x) (x >> 8) +#define IOC_FUNC(x) (x & 0xff) + +static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil_list **xperms_list) +{ + ebitmap_node_t *node; + unsigned int i; + uint16_t low = 0, high = 0; + struct avtab_extended_perms *partial = NULL; + struct avtab_extended_perms *complete = NULL; + int start_new_range; + + cil_list_init(xperms_list, CIL_NONE); + + start_new_range = 1; + + ebitmap_for_each_positive_bit(xperms, node, i) { + if (start_new_range) { + low = i; + start_new_range = 0; + } + + // continue if the current bit isn't the end of the driver function or the next bit is set + if (IOC_FUNC(i) != 0xff && ksu_ebitmap_get_bit(xperms, i + 1)) { + continue; + } + + // if we got here, i is the end of this range (either because the func + // is 0xff or the next bit isn't set). The next time around we are + // going to need a start a new range + high = i; + start_new_range = 1; + + if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) { + if (!complete) { + complete = cil_calloc(1, sizeof(*complete)); + complete->driver = 0x0; + complete->specified = AVTAB_XPERMS_IOCTLDRIVER; + } + + __avrule_xperm_setrangebits(IOC_DRIV(low), IOC_DRIV(low), complete); + } else { + if (partial && partial->driver != IOC_DRIV(low)) { + cil_list_append(*xperms_list, CIL_NONE, partial); + partial = NULL; + } + + if (!partial) { + partial = cil_calloc(1, sizeof(*partial)); + partial->driver = IOC_DRIV(low); + partial->specified = AVTAB_XPERMS_IOCTLFUNCTION; + } + + __avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial); + } + } + + if (partial) { + cil_list_append(*xperms_list, CIL_NONE, partial); + } + + if (complete) { + cil_list_append(*xperms_list, CIL_NONE, complete); + } + + return SEPOL_OK; +} + +static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) +{ + int rc = SEPOL_OK; + struct policydb *pdb; + avtab_key_t *avtab_key; + avtab_datum_t avtab_datum; + struct cil_list *xperms_list = NULL; + struct cil_list_item *item; + class_datum_t *sepol_obj; + uint32_t data = 0; + + avtab_key = (avtab_key_t *)k; + pdb = args; + + sepol_obj = pdb->class_val_to_struct[avtab_key->target_class - 1]; + + // setting the data for an extended avtab isn't really necessary because + // it is ignored by the kernel. However, neverallow checking requires that + // the data value be set, so set it for that to work. + rc = __perm_str_to_datum(CIL_KEY_IOCTL, sepol_obj, &data); + if (rc != SEPOL_OK) { + goto exit; + } + avtab_datum.data = data; + + rc = __cil_permx_bitmap_to_sepol_xperms_list(datum, &xperms_list); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_list_for_each(item, xperms_list) { + avtab_datum.xperms = item->data; + rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum); + if (rc != SEPOL_OK) { + goto exit; + } + } + + rc = SEPOL_OK; + +exit: + if (xperms_list != NULL) { + cil_list_for_each(item, xperms_list) { + free(item->data); + } + cil_list_destroy(&xperms_list, CIL_FALSE); + } + return rc; +} + +static int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms) +{ + uint16_t specified; + avtab_key_t *avtab_key; + ebitmap_t *hashtab_xperms; + int rc = SEPOL_ERR; + + switch (kind) { + case CIL_AVRULE_ALLOWED: + specified = AVTAB_XPERMS_ALLOWED; + break; + case CIL_AVRULE_AUDITALLOW: + specified = AVTAB_XPERMS_AUDITALLOW; + break; + case CIL_AVRULE_DONTAUDIT: + specified = AVTAB_XPERMS_DONTAUDIT; + break; + default: + rc = SEPOL_ERR; + goto exit; + } + + avtab_key = cil_malloc(sizeof(*avtab_key)); + avtab_key->source_type = src; + avtab_key->target_type = tgt; + avtab_key->target_class = obj; + avtab_key->specified = specified; + + hashtab_xperms = (ebitmap_t *)hashtab_search(h, (hashtab_key_t)avtab_key); + if (!hashtab_xperms) { + hashtab_xperms = cil_malloc(sizeof(*hashtab_xperms)); + rc = ksu_ebitmap_cpy(hashtab_xperms, xperms); + if (rc != SEPOL_OK) { + free(hashtab_xperms); + free(avtab_key); + goto exit; + } + rc = hashtab_insert(h, (hashtab_key_t)avtab_key, hashtab_xperms); + if (rc != SEPOL_OK) { + free(hashtab_xperms); + free(avtab_key); + goto exit; + } + } else { + free(avtab_key); + rc = ebitmap_union(hashtab_xperms, xperms); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_permissionx *permx, struct cil_args_binary *args) +{ + int rc = SEPOL_ERR; + type_datum_t *sepol_src = NULL; + type_datum_t *sepol_tgt = NULL; + class_datum_t *sepol_obj = NULL; + struct cil_list *class_list = NULL; + struct cil_list_item *c; + + rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt); + if (rc != SEPOL_OK) goto exit; + + class_list = cil_expand_class(permx->obj); + + cil_list_for_each(c, class_list) { + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); + if (rc != SEPOL_OK) goto exit; + + switch (permx->kind) { + case CIL_PERMX_KIND_IOCTL: + rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); + if (rc != SEPOL_OK) goto exit; + break; + default: + rc = SEPOL_ERR; + goto exit; + } + } + + rc = SEPOL_OK; + +exit: + cil_list_destroy(&class_list, CIL_FALSE); + + return rc; +} + +static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrulex, struct cil_args_binary *args) +{ + int rc = SEPOL_ERR; + uint16_t kind; + struct cil_symtab_datum *src = NULL; + struct cil_symtab_datum *tgt = NULL; + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *snode, *tnode; + unsigned int s,t; + + if (cil_avrulex->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) { + // Do not add dontaudit rules to binary + rc = SEPOL_OK; + goto exit; + } + + kind = cil_avrulex->rule_kind; + src = cil_avrulex->src; + tgt = cil_avrulex->tgt; + + if (tgt->fqn == CIL_KEY_SELF) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { + src = DATUM(db->val_to_type[s]); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + goto exit; + } + } + ksu_ebitmap_destroy(&src_bitmap); + } else { + int expand_src = __cil_should_expand_attribute(db, src); + int expand_tgt = __cil_should_expand_attribute(db, tgt); + + if (!expand_src && !expand_tgt) { + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + goto exit; + } + } else if (expand_src && expand_tgt) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&src_bitmap); + goto exit; + } + + ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { + src = DATUM(db->val_to_type[s]); + ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) { + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + } + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + } else if (expand_src) { + rc = __cil_expand_type(src, &src_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { + src = DATUM(db->val_to_type[s]); + + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&src_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&src_bitmap); + } else { /* expand_tgt */ + rc = __cil_expand_type(tgt, &tgt_bitmap); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) { + tgt = DATUM(db->val_to_type[t]); + + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&tgt_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&tgt_bitmap); + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args) +{ + free(k); + ksu_ebitmap_destroy(datum); + free(datum); + + return SEPOL_OK; +} + +static int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) +{ + int rc; + enum cil_flavor flavor; + struct cil_args_booleanif *args = extra_args; + const struct cil_db *db = args->db; + policydb_t *pdb = args->pdb; + cond_node_t *cond_node = args->cond_node; + enum cil_flavor cond_flavor = args->cond_flavor; + struct cil_type_rule *cil_type_rule; + struct cil_avrule *cil_avrule; + struct cil_nametypetransition *cil_typetrans; + + flavor = node->flavor; + switch (flavor) { + case CIL_NAMETYPETRANSITION: + cil_typetrans = (struct cil_nametypetransition*)node->data; + if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) { + cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n"); + cil_tree_log(node, CIL_ERR,"Invalid typetransition statement"); + goto exit; + } + rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_ERR, "Failed to insert type transition into avtab"); + goto exit; + } + break; + case CIL_TYPE_RULE: + cil_type_rule = node->data; + rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_ERR, "Failed to insert typerule into avtab"); + goto exit; + } + break; + case CIL_AVRULE: + cil_avrule = node->data; + rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_ERR, "Failed to insert avrule into avtab"); + goto exit; + } + break; + case CIL_CALL: + case CIL_TUNABLEIF: + break; + default: + cil_tree_log(node, CIL_ERR, "Invalid statement within booleanif"); + goto exit; + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out); + +static void __cil_expr_to_string_helper(struct cil_list_item *curr, enum cil_flavor flavor, char **out) +{ + char *c; + + if (curr->flavor == CIL_DATUM) { + *out = cil_strdup(DATUM(curr->data)->fqn); + } else if (curr->flavor == CIL_LIST) { + __cil_expr_to_string(curr->data, flavor, &c); + cil_asprintf(out, "(%s)", c); + free(c); + } else if (flavor == CIL_PERMISSIONX) { + // permissionx expressions aren't resolved into anything, so curr->flavor + // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those + *out = cil_strdup(curr->data); + } +} + +static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out) +{ + struct cil_list_item *curr; + char *s1 = NULL; + char *s2 = NULL; + enum cil_flavor op; + + if (expr == NULL || expr->head == NULL) { + *out = cil_strdup(""); + return; + } + + curr = expr->head; + + if (curr->flavor == CIL_OP) { + op = (enum cil_flavor)(uintptr_t)curr->data; + + if (op == CIL_ALL) { + *out = cil_strdup(CIL_KEY_ALL); + } else if (op == CIL_RANGE) { + __cil_expr_to_string_helper(curr->next, flavor, &s1); + __cil_expr_to_string_helper(curr->next->next, flavor, &s2); + cil_asprintf(out, "%s %s %s", CIL_KEY_RANGE, s1, s2); + free(s1); + free(s2); + } else { + __cil_expr_to_string_helper(curr->next, flavor, &s1); + + if (op == CIL_NOT) { + cil_asprintf(out, "%s %s", CIL_KEY_NOT, s1); + free(s1); + } else { + const char *opstr = ""; + + __cil_expr_to_string_helper(curr->next->next, flavor, &s2); + + if (op == CIL_OR) { + opstr = CIL_KEY_OR; + } else if (op == CIL_AND) { + opstr = CIL_KEY_AND; + } else if (op == CIL_XOR) { + opstr = CIL_KEY_XOR; + } + + cil_asprintf(out, "%s %s %s", opstr, s1, s2); + free(s1); + free(s2); + } + } + } else { + char *c1 = NULL; + char *c2 = NULL; + __cil_expr_to_string_helper(curr, flavor, &c1); + for (curr = curr->next; curr; curr = curr->next) { + s1 = NULL; + __cil_expr_to_string_helper(curr, flavor, &s1); + cil_asprintf(&c2, "%s %s", c1, s1); + free(c1); + free(s1); + c1 = c2; + } + *out = c1; + } +} + +static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail); + +static int __cil_cond_item_to_sepol_expr(policydb_t *pdb, struct cil_list_item *item, cond_expr_t **head, cond_expr_t **tail) +{ + if (item == NULL) { + goto exit; + } else if (item->flavor == CIL_DATUM) { + char *key = DATUM(item->data)->fqn; + cond_bool_datum_t *sepol_bool = hashtab_search(pdb->p_bools.table, key); + if (sepol_bool == NULL) { + cil_log(CIL_INFO, "Failed to find boolean\n"); + goto exit; + } + *head = cil_malloc(sizeof(cond_expr_t)); + (*head)->next = NULL; + (*head)->expr_type = COND_BOOL; + (*head)->bool = sepol_bool->s.value; + *tail = *head; + } else if (item->flavor == CIL_LIST) { + struct cil_list *l = item->data; + int rc = __cil_cond_expr_to_sepol_expr_helper(pdb, l, head, tail); + if (rc != SEPOL_OK) { + goto exit; + } + } else { + goto exit; + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail) +{ + int rc = SEPOL_ERR; + struct cil_list_item *item = cil_expr->head; + enum cil_flavor flavor = cil_expr->flavor; + cond_expr_t *op, *h1, *h2, *t1, *t2; + + if (flavor != CIL_BOOL) { + cil_log(CIL_INFO, "Expected boolean expression\n"); + goto exit; + } + + if (item == NULL) { + goto exit; + } else if (item->flavor == CIL_OP) { + enum cil_flavor cil_op = (enum cil_flavor)(uintptr_t)item->data; + + op = cil_malloc(sizeof(*op)); + op->bool = 0; + op->next = NULL; + + switch (cil_op) { + case CIL_NOT: + op->expr_type = COND_NOT; + break; + case CIL_OR: + op->expr_type = COND_OR; + break; + case CIL_AND: + op->expr_type = COND_AND; + break; + case CIL_XOR: + op->expr_type = COND_XOR; + break; + case CIL_EQ: + op->expr_type = COND_EQ; + break; + case CIL_NEQ: + op->expr_type = COND_NEQ; + break; + default: + free(op); + goto exit; + } + + rc = __cil_cond_item_to_sepol_expr(pdb, item->next, &h1, &t1); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to get first operand of conditional expression\n"); + free(op); + goto exit; + } + + if (cil_op == CIL_NOT) { + *head = h1; + t1->next = op; + *tail = op; + } else { + rc = __cil_cond_item_to_sepol_expr(pdb, item->next->next, &h2, &t2); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to get second operand of conditional expression\n"); + free(op); + cond_expr_destroy(h1); + goto exit; + } + + *head = h1; + t1->next = h2; + t2->next = op; + *tail = op; + } + } else { + rc = __cil_cond_item_to_sepol_expr(pdb, item, &h1, &t1); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to get initial item in conditional list\n"); + goto exit; + } + *head = h1; + for (item = item->next; item; item = item->next) { + rc = __cil_cond_item_to_sepol_expr(pdb, item, &h2, &t2); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to get item in conditional list\n"); + cond_expr_destroy(*head); + goto exit; + } + op = cil_malloc(sizeof(*op)); + op->bool = 0; + op->next = NULL; + op->expr_type = COND_OR; + t1->next = h2; + t2->next = op; + t1 = op; + } + *tail = t1; + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **sepol_expr) +{ + int rc; + cond_expr_t *head, *tail; + + rc = __cil_cond_expr_to_sepol_expr_helper(pdb, cil_expr, &head, &tail); + if (rc != SEPOL_OK) { + return SEPOL_ERR; + } + *sepol_expr = head; + + return SEPOL_OK; +} + +static int __cil_validate_cond_expr(cond_expr_t *cond_expr) +{ + cond_expr_t *e; + int depth = -1; + + for (e = cond_expr; e != NULL; e = e->next) { + switch (e->expr_type) { + case COND_BOOL: + if (depth == (COND_EXPR_MAXDEPTH - 1)) { + cil_log(CIL_ERR,"Conditional expression exceeded max allowable depth\n"); + return SEPOL_ERR; + } + depth++; + break; + case COND_NOT: + if (depth < 0) { + cil_log(CIL_ERR,"Invalid conditional expression\n"); + return SEPOL_ERR; + } + break; + case COND_OR: + case COND_AND: + case COND_XOR: + case COND_EQ: + case COND_NEQ: + if (depth < 1) { + cil_log(CIL_ERR,"Invalid conditional expression\n"); + return SEPOL_ERR; + } + depth--; + break; + default: + cil_log(CIL_ERR,"Invalid conditional expression\n"); + return SEPOL_ERR; + } + } + + if (depth != 0) { + cil_log(CIL_ERR,"Invalid conditional expression\n"); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_args_booleanif bool_args; + struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data; + struct cil_tree_node *cb_node; + struct cil_tree_node *true_node = NULL; + struct cil_tree_node *false_node = NULL; + struct cil_tree_node *tmp_node = NULL; + cond_node_t *tmp_cond = NULL; + cond_node_t *cond_node = NULL; + int was_created; + int swapped = CIL_FALSE; + cond_av_list_t tmp_cl; + + tmp_cond = cond_node_create(pdb, NULL); + if (tmp_cond == NULL) { + rc = SEPOL_ERR; + cil_tree_log(node, CIL_INFO, "Failed to create sepol conditional node"); + goto exit; + } + + rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_INFO, "Failed to convert CIL conditional expression to sepol expression"); + goto exit; + } + + rc = __cil_validate_cond_expr(tmp_cond->expr); + if (rc != SEPOL_OK) { + goto exit; + } + + tmp_cond->true_list = &tmp_cl; + + rc = cond_normalize_expr(pdb, tmp_cond); + if (rc != SEPOL_OK) { + goto exit; + } + + if (tmp_cond->false_list != NULL) { + tmp_cond->true_list = NULL; + swapped = CIL_TRUE; + } + + cond_node = cond_node_find(pdb, tmp_cond, pdb->cond_list, &was_created); + if (cond_node == NULL) { + rc = SEPOL_ERR; + goto exit; + } + + if (was_created) { + cond_node->next = pdb->cond_list; + pdb->cond_list = cond_node; + } + + cond_expr_destroy(tmp_cond->expr); + free(tmp_cond); + tmp_cond = NULL; + + for (cb_node = node->cl_head; cb_node != NULL; cb_node = cb_node->next) { + if (cb_node->flavor == CIL_CONDBLOCK) { + struct cil_condblock *cb = cb_node->data; + if (cb->flavor == CIL_CONDTRUE) { + true_node = cb_node; + } else if (cb->flavor == CIL_CONDFALSE) { + false_node = cb_node; + } + } + } + + if (swapped) { + tmp_node = true_node; + true_node = false_node; + false_node = tmp_node; + } + + bool_args.db = db; + bool_args.pdb = pdb; + bool_args.cond_node = cond_node; + + if (true_node != NULL) { + bool_args.cond_flavor = CIL_CONDTRUE; + rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); + if (rc != SEPOL_OK) { + cil_tree_log(true_node, CIL_ERR, "Failure while walking true conditional block"); + goto exit; + } + } + + if (false_node != NULL) { + bool_args.cond_flavor = CIL_CONDFALSE; + rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); + if (rc != SEPOL_OK) { + cil_tree_log(false_node, CIL_ERR, "Failure while walking false conditional block"); + goto exit; + } + } + + return SEPOL_OK; + +exit: + if (tmp_cond) { + if (tmp_cond->expr) + cond_expr_destroy(tmp_cond->expr); + free(tmp_cond); + } + return rc; +} + +int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table) +{ + int rc = SEPOL_ERR; + role_datum_t *sepol_src = NULL; + type_datum_t *sepol_tgt = NULL; + class_datum_t *sepol_obj = NULL; + struct cil_list *class_list = NULL; + role_datum_t *sepol_result = NULL; + role_trans_t *new = NULL; + uint32_t *new_role = NULL; + ebitmap_t role_bitmap, type_bitmap; + ebitmap_node_t *rnode, *tnode; + unsigned int i, j; + struct cil_list_item *c; + + rc = __cil_expand_role(DATUM(roletrans->src), &role_bitmap); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_expand_type(roletrans->tgt, &type_bitmap); + if (rc != SEPOL_OK) goto exit; + + class_list = cil_expand_class(roletrans->obj); + + rc = __cil_get_sepol_role_datum(pdb, DATUM(roletrans->result), &sepol_result); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&role_bitmap, rnode, i) { + rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&type_bitmap, tnode, j) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); + if (rc != SEPOL_OK) goto exit; + + cil_list_for_each(c, class_list) { + int add = CIL_TRUE; + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); + if (rc != SEPOL_OK) goto exit; + + new = cil_malloc(sizeof(*new)); + memset(new, 0, sizeof(*new)); + new->role = sepol_src->s.value; + new->type = sepol_tgt->s.value; + new->tclass = sepol_obj->s.value; + new->new_role = sepol_result->s.value; + + rc = hashtab_insert(role_trans_table, (hashtab_key_t)new, &(new->new_role)); + if (rc != SEPOL_OK) { + if (rc == SEPOL_EEXIST) { + add = CIL_FALSE; + new_role = hashtab_search(role_trans_table, (hashtab_key_t)new); + if (new->new_role != *new_role) { + cil_log(CIL_ERR, "Conflicting role transition rules\n"); + } else { + rc = SEPOL_OK; + } + } else { + cil_log(CIL_ERR, "Out of memory\n"); + } + } + + if (add == CIL_TRUE) { + new->next = pdb->role_tr; + pdb->role_tr = new; + } else { + free(new); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + } + } + + rc = SEPOL_OK; + +exit: + ksu_ebitmap_destroy(&role_bitmap); + ksu_ebitmap_destroy(&type_bitmap); + cil_list_destroy(&class_list, CIL_FALSE); + return rc; +} + +int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow) +{ + int rc = SEPOL_ERR; + role_datum_t *sepol_src = NULL; + role_datum_t *sepol_tgt = NULL; + role_allow_t *sepol_roleallow = NULL; + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *node1, *node2; + unsigned int i, j; + + rc = __cil_expand_role(roleallow->src, &src_bitmap); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_expand_role(roleallow->tgt, &tgt_bitmap); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&src_bitmap, node1, i) { + rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) { + rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[j]), &sepol_tgt); + if (rc != SEPOL_OK) goto exit; + + sepol_roleallow = cil_malloc(sizeof(*sepol_roleallow)); + memset(sepol_roleallow, 0, sizeof(role_allow_t)); + sepol_roleallow->role = sepol_src->s.value; + sepol_roleallow->new_role = sepol_tgt->s.value; + + sepol_roleallow->next = pdb->role_allow; + pdb->role_allow = sepol_roleallow; + } + } + + rc = SEPOL_OK; + +exit: + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + return rc; +} + +static int __cil_constrain_expr_datum_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *item, enum cil_flavor expr_flavor, constraint_expr_t *expr) +{ + int rc = SEPOL_ERR; + + if (expr_flavor == CIL_USER) { + user_datum_t *sepol_user = NULL; + ebitmap_t user_bitmap; + ebitmap_node_t *unode; + unsigned int i; + + rc = __cil_expand_user(item->data, &user_bitmap); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&user_bitmap, unode, i) { + rc = __cil_get_sepol_user_datum(pdb, DATUM(db->val_to_user[i]), &sepol_user); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&user_bitmap); + goto exit; + } + + if (ksu_ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) { + ksu_ebitmap_destroy(&user_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&user_bitmap); + } else if (expr_flavor == CIL_ROLE) { + role_datum_t *sepol_role = NULL; + ebitmap_t role_bitmap; + ebitmap_node_t *rnode; + unsigned int i; + + rc = __cil_expand_role(item->data, &role_bitmap); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&role_bitmap, rnode, i) { + rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&role_bitmap); + goto exit; + } + + if (ksu_ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) { + ksu_ebitmap_destroy(&role_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&role_bitmap); + } else if (expr_flavor == CIL_TYPE) { + type_datum_t *sepol_type = NULL; + ebitmap_t type_bitmap; + ebitmap_node_t *tnode; + unsigned int i; + + if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) { + rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type); + if (rc != SEPOL_OK) { + if (FLAVOR(item->data) == CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *attr = item->data; + if (!attr->keep) { + rc = 0; + } + } + } + + if (sepol_type) { + rc = ksu_ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1); + } + + if (rc != SEPOL_OK) { + goto exit; + } + } + + rc = __cil_expand_type(item->data, &type_bitmap); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&type_bitmap, tnode, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&type_bitmap); + goto exit; + } + + if (ksu_ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) { + ksu_ebitmap_destroy(&type_bitmap); + goto exit; + } + } + ksu_ebitmap_destroy(&type_bitmap); + } else { + goto exit; + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *op_item, enum cil_flavor expr_flavor, constraint_expr_t *expr) +{ + int rc = SEPOL_ERR; + struct cil_list_item *l_item = op_item->next; + struct cil_list_item *r_item = op_item->next->next; + + enum cil_flavor l_operand = (enum cil_flavor)(uintptr_t)l_item->data; + + switch (l_operand) { + case CIL_CONS_U1: + expr->attr = CEXPR_USER; + break; + case CIL_CONS_U2: + expr->attr = CEXPR_USER | CEXPR_TARGET; + break; + case CIL_CONS_U3: + expr->attr = CEXPR_USER | CEXPR_XTARGET; + break; + case CIL_CONS_R1: + expr->attr = CEXPR_ROLE; + break; + case CIL_CONS_R2: + expr->attr = CEXPR_ROLE | CEXPR_TARGET; + break; + case CIL_CONS_R3: + expr->attr = CEXPR_ROLE | CEXPR_XTARGET; + break; + case CIL_CONS_T1: + expr->attr = CEXPR_TYPE; + break; + case CIL_CONS_T2: + expr->attr = CEXPR_TYPE | CEXPR_TARGET; + break; + case CIL_CONS_T3: + expr->attr = CEXPR_TYPE | CEXPR_XTARGET; + break; + case CIL_CONS_L1: { + enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data; + + if (r_operand == CIL_CONS_L2) { + expr->attr = CEXPR_L1L2; + } else if (r_operand == CIL_CONS_H1) { + expr->attr = CEXPR_L1H1; + } else { + expr->attr = CEXPR_L1H2; + } + break; + } + case CIL_CONS_L2: + expr->attr = CEXPR_L2H2; + break; + case CIL_CONS_H1: { + enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data; + if (r_operand == CIL_CONS_L2) { + expr->attr = CEXPR_H1L2; + } else { + expr->attr = CEXPR_H1H2; + } + break; + } + default: + goto exit; + break; + } + + if (r_item->flavor == CIL_CONS_OPERAND) { + expr->expr_type = CEXPR_ATTR; + } else { + expr->expr_type = CEXPR_NAMES; + if (r_item->flavor == CIL_DATUM) { + rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, r_item, expr_flavor, expr); + if (rc != SEPOL_OK) { + goto exit; + } + } else if (r_item->flavor == CIL_LIST) { + struct cil_list *r_expr = r_item->data; + struct cil_list_item *curr; + cil_list_for_each(curr, r_expr) { + rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, curr, expr_flavor, expr); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else { + rc = SEPOL_ERR; + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **head, constraint_expr_t **tail) +{ + int rc = SEPOL_ERR; + struct cil_list_item *item; + enum cil_flavor flavor; + enum cil_flavor cil_op; + constraint_expr_t *op, *h1, *h2, *t1, *t2; + int is_leaf = CIL_FALSE; + + if (cil_expr == NULL) { + return SEPOL_ERR; + } + + item = cil_expr->head; + flavor = cil_expr->flavor; + + op = cil_malloc(sizeof(constraint_expr_t)); + rc = constraint_expr_init(op); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_op = (enum cil_flavor)(uintptr_t)item->data; + switch (cil_op) { + case CIL_NOT: + op->expr_type = CEXPR_NOT; + break; + case CIL_AND: + op->expr_type = CEXPR_AND; + break; + case CIL_OR: + op->expr_type = CEXPR_OR; + break; + case CIL_EQ: + op->op = CEXPR_EQ; + is_leaf = CIL_TRUE; + break; + case CIL_NEQ: + op->op = CEXPR_NEQ; + is_leaf = CIL_TRUE; + break; + case CIL_CONS_DOM: + op->op = CEXPR_DOM; + is_leaf = CIL_TRUE; + break; + case CIL_CONS_DOMBY: + op->op = CEXPR_DOMBY; + is_leaf = CIL_TRUE; + break; + case CIL_CONS_INCOMP: + op->op = CEXPR_INCOMP; + is_leaf = CIL_TRUE; + break; + default: + goto exit; + } + + if (is_leaf == CIL_TRUE) { + rc = __cil_constrain_expr_leaf_to_sepol_expr(pdb, db, item, flavor, op); + if (rc != SEPOL_OK) { + goto exit; + } + *head = op; + *tail = op; + } else if (cil_op == CIL_NOT) { + struct cil_list *l_expr = item->next->data; + rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1); + if (rc != SEPOL_OK) { + goto exit; + } + t1->next = op; + *head = h1; + *tail = op; + } else { + struct cil_list *l_expr = item->next->data; + struct cil_list *r_expr = item->next->next->data; + rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1); + if (rc != SEPOL_OK) { + goto exit; + } + rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, r_expr, &h2, &t2); + if (rc != SEPOL_OK) { + constraint_expr_destroy(h1); + goto exit; + } + t1->next = h2; + t2->next = op; + *head = h1; + *tail = op; + } + + return SEPOL_OK; + +exit: + constraint_expr_destroy(op); + return SEPOL_ERR; +} + +static int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **sepol_expr) +{ + int rc; + constraint_expr_t *head, *tail; + + rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, cil_expr, &head, &tail); + if (rc != SEPOL_OK) { + return SEPOL_ERR; + } + + *sepol_expr = head; + + return SEPOL_OK; +} + +static int __cil_validate_constrain_expr(constraint_expr_t *sepol_expr) +{ + constraint_expr_t *e; + int depth = -1; + + for (e = sepol_expr; e != NULL; e = e->next) { + switch (e->expr_type) { + case CEXPR_NOT: + if (depth < 0) { + cil_log(CIL_ERR,"Invalid constraint expression\n"); + return SEPOL_ERR; + } + break; + case CEXPR_AND: + case CEXPR_OR: + if (depth < 1) { + cil_log(CIL_ERR,"Invalid constraint expression\n"); + return SEPOL_ERR; + } + depth--; + break; + case CEXPR_ATTR: + case CEXPR_NAMES: + if (depth == (CEXPR_MAXDEPTH - 1)) { + cil_log(CIL_ERR,"Constraint expression exceeded max allowable depth\n"); + return SEPOL_ERR; + } + depth++; + break; + default: + cil_log(CIL_ERR,"Invalid constraint expression\n"); + return SEPOL_ERR; + } + } + + if (depth != 0) { + cil_log(CIL_ERR,"Invalid constraint expression\n"); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr) +{ + int rc = SEPOL_ERR; + constraint_node_t *sepol_constrain = NULL; + constraint_expr_t *sepol_expr = NULL; + class_datum_t *sepol_class = NULL; + + sepol_constrain = cil_malloc(sizeof(*sepol_constrain)); + memset(sepol_constrain, 0, sizeof(constraint_node_t)); + + rc = __cil_get_sepol_class_datum(pdb, class, &sepol_class); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_perms_to_datum(perms, sepol_class, &sepol_constrain->permissions); + if (rc != SEPOL_OK) { + goto exit; + } + + if (sepol_constrain->permissions == 0) { + /* No permissions, so don't insert rule. */ + free(sepol_constrain); + return SEPOL_OK; + } + + rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_validate_constrain_expr(sepol_expr); + if (rc != SEPOL_OK) { + goto exit; + } + + sepol_constrain->expr = sepol_expr; + sepol_constrain->next = sepol_class->constraints; + sepol_class->constraints = sepol_constrain; + + return SEPOL_OK; + +exit: + constraint_expr_destroy(sepol_expr); + free(sepol_constrain); + return rc; +} + +static int cil_constrain_expand(policydb_t *pdb, const struct cil_db *db, struct cil_list *classperms, struct cil_list *expr) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + + cil_list_for_each(curr, classperms) { + if (curr->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = curr->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + rc = cil_constrain_to_policydb_helper(pdb, db, DATUM(cp->class), cp->perms, expr); + if (rc != SEPOL_OK) { + goto exit; + } + } else { /* MAP */ + struct cil_list_item *i = NULL; + cil_list_for_each(i, cp->perms) { + struct cil_perm *cmp = i->data; + rc = cil_constrain_expand(pdb, db, cmp->classperms, expr); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + rc = cil_constrain_expand(pdb, db, cp->classperms, expr); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain) +{ + int rc = SEPOL_ERR; + rc = cil_constrain_expand(pdb, db, cil_constrain->classperms, cil_constrain->datum_expr); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to insert constraint into policydb\n"); + return rc; +} + +static int cil_validatetrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_validatetrans *cil_validatetrans) +{ + int rc = SEPOL_ERR; + struct cil_list *expr = cil_validatetrans->datum_expr; + class_datum_t *sepol_class = NULL; + struct cil_list *class_list; + constraint_node_t *sepol_validatetrans = NULL; + constraint_expr_t *sepol_expr = NULL; + struct cil_list_item *c; + + class_list = cil_expand_class(cil_validatetrans->class); + + cil_list_for_each(c, class_list) { + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); + if (rc != SEPOL_OK) goto exit; + + sepol_validatetrans = cil_malloc(sizeof(*sepol_validatetrans)); + memset(sepol_validatetrans, 0, sizeof(constraint_node_t)); + + rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr); + if (rc != SEPOL_OK) { + free(sepol_validatetrans); + goto exit; + } + sepol_validatetrans->expr = sepol_expr; + + sepol_validatetrans->next = sepol_class->validatetrans; + sepol_class->validatetrans = sepol_validatetrans; + } + + rc = SEPOL_OK; + +exit: + cil_list_destroy(&class_list, CIL_FALSE); + return rc; +} + +static int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t *mls_level) +{ + int rc = SEPOL_ERR; + struct cil_list_item *i; + cat_datum_t *sepol_cat = NULL; + + cil_list_for_each(i, cats->datum_expr) { + struct cil_tree_node *node = NODE(i->data); + if (node->flavor == CIL_CATSET) { + struct cil_list_item *j; + struct cil_catset *cs = i->data; + cil_list_for_each(j, cs->cats->datum_expr) { + rc = __cil_get_sepol_cat_datum(pdb, j->data, &sepol_cat); + if (rc != SEPOL_OK) goto exit; + + rc = ksu_ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1); + if (rc != SEPOL_OK) goto exit; + } + } else { + rc = __cil_get_sepol_cat_datum(pdb, i->data, &sepol_cat); + if (rc != SEPOL_OK) goto exit; + + rc = ksu_ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1); + if (rc != SEPOL_OK) goto exit; + } + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + level_datum_t *sepol_level = NULL; + mls_level_t *mls_level = NULL; + + rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level); + if (rc != SEPOL_OK) goto exit; + + mls_level = sepol_level->level; + + ebitmap_init(&mls_level->cat); + + if (cil_sens->cats_list) { + cil_list_for_each(curr, cil_sens->cats_list) { + struct cil_cats *cats = curr->data; + rc = __cil_cats_to_mls_level(pdb, cats, mls_level); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n"); + goto exit; + } + } + } + + sepol_level->defined = 1; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level) +{ + int rc = SEPOL_ERR; + struct cil_sens *cil_sens = cil_level->sens; + struct cil_cats *cats = cil_level->cats; + level_datum_t *sepol_level = NULL; + + rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level); + if (rc != SEPOL_OK) goto exit; + + mls_level->sens = sepol_level->level->sens; + + ebitmap_init(&mls_level->cat); + + if (cats != NULL) { + rc = __cil_cats_to_mls_level(pdb, cats, mls_level); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n"); + goto exit; + } + } + + rc = SEPOL_OK; +exit: + return rc; +} + +static int __cil_levelrange_to_mls_range(policydb_t *pdb, struct cil_levelrange *cil_lvlrange, mls_range_t *mls_range) +{ + int rc = SEPOL_ERR; + struct cil_level *low = cil_lvlrange->low; + struct cil_level *high = cil_lvlrange->high; + mls_level_t *mls_level = NULL; + + mls_level = &mls_range->level[0]; + + rc = cil_level_to_mls_level(pdb, low, mls_level); + if (rc != SEPOL_OK) { + goto exit; + } + + mls_level = &mls_range->level[1]; + + rc = cil_level_to_mls_level(pdb, high, mls_level); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_userlevel_userrange_to_policydb(policydb_t *pdb, struct cil_user *cil_user) +{ + int rc = SEPOL_ERR; + struct cil_level *cil_level = cil_user->dftlevel; + struct cil_levelrange *cil_levelrange = cil_user->range; + user_datum_t *sepol_user = NULL; + + rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user); + if (rc != SEPOL_OK) goto exit; + + rc = cil_level_to_mls_level(pdb, cil_level, &sepol_user->exp_dfltlevel); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_levelrange_to_mls_range(pdb, cil_levelrange, &sepol_user->exp_range); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_context_to_sepol_context(policydb_t *pdb, struct cil_context *cil_context, context_struct_t *sepol_context) +{ + int rc = SEPOL_ERR; + struct cil_levelrange *cil_lvlrange = cil_context->range; + user_datum_t *sepol_user = NULL; + role_datum_t *sepol_role = NULL; + type_datum_t *sepol_type = NULL; + + rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_context->user), &sepol_user); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_context->role), &sepol_role); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_context->type), &sepol_type); + if (rc != SEPOL_OK) goto exit; + + sepol_context->user = sepol_user->s.value; + sepol_context->role = sepol_role->s.value; + sepol_context->type = sepol_type->s.value; + + if (pdb->mls == CIL_TRUE) { + mls_context_init(sepol_context); + + rc = __cil_levelrange_to_mls_range(pdb, cil_lvlrange, &sepol_context->range); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR,"Problem with MLS\n"); + mls_context_destroy(sepol_context); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + unsigned count = 0; + ocontext_t *tail = NULL; + + if (db->sidorder == NULL || db->sidorder->head == NULL) { + cil_log(CIL_WARN, "No sidorder statement in policy\n"); + return SEPOL_OK; + } + + cil_list_for_each(curr, db->sidorder) { + struct cil_sid *cil_sid = (struct cil_sid*)curr->data; + struct cil_context *cil_context = cil_sid->context; + + /* even if no context, we must preserve initial SID values */ + count++; + + if (cil_context != NULL) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail); + new_ocon->sid[0] = count; + new_ocon->u.name = cil_strdup(cil_sid->datum.fqn); + rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR,"Problem with context for SID %s\n",cil_sid->datum.fqn); + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans) +{ + int rc = SEPOL_ERR; + type_datum_t *sepol_src = NULL; + type_datum_t *sepol_tgt = NULL; + class_datum_t *sepol_class = NULL; + struct cil_list *class_list = NULL; + range_trans_t *newkey = NULL; + struct mls_range *newdatum = NULL; + ebitmap_t src_bitmap, tgt_bitmap; + ebitmap_node_t *node1, *node2; + unsigned int i, j; + struct cil_list_item *c; + struct mls_range *o_range = NULL; + + rc = __cil_expand_type(rangetrans->src, &src_bitmap); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_expand_type(rangetrans->exec, &tgt_bitmap); + if (rc != SEPOL_OK) goto exit; + + class_list = cil_expand_class(rangetrans->obj); + + ebitmap_for_each_positive_bit(&src_bitmap, node1, i) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); + if (rc != SEPOL_OK) goto exit; + + ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) { + rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); + if (rc != SEPOL_OK) goto exit; + + cil_list_for_each(c, class_list) { + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); + if (rc != SEPOL_OK) goto exit; + + newkey = cil_calloc(1, sizeof(*newkey)); + newdatum = cil_calloc(1, sizeof(*newdatum)); + newkey->source_type = sepol_src->s.value; + newkey->target_type = sepol_tgt->s.value; + newkey->target_class = sepol_class->s.value; + rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, newdatum); + if (rc != SEPOL_OK) { + free(newkey); + free(newdatum); + goto exit; + } + + rc = hashtab_insert(pdb->range_tr, (hashtab_key_t)newkey, newdatum); + if (rc != SEPOL_OK) { + if (rc == SEPOL_EEXIST) { + o_range = hashtab_search(pdb->range_tr, (hashtab_key_t)newkey); + if (!mls_range_eq(newdatum, o_range)) { + cil_log(CIL_ERR, "Conflicting Range transition rules\n"); + } else { + rc = SEPOL_OK; + } + } else { + cil_log(CIL_ERR, "Out of memory\n"); + } +// TODO: add upper version bound once fixed in upstream GCC +#if defined(__GNUC__) && (__GNUC__ >= 12) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +# pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + mls_range_destroy(newdatum); +#if defined(__GNUC__) && (__GNUC__ >= 12) +# pragma GCC diagnostic pop +#endif + free(newdatum); + free(newkey); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + } + } + + rc = SEPOL_OK; + +exit: + ksu_ebitmap_destroy(&src_bitmap); + ksu_ebitmap_destroy(&tgt_bitmap); + cil_list_destroy(&class_list, CIL_FALSE); + return rc; +} + +int cil_ibpkeycon_to_policydb(policydb_t *pdb, struct cil_sort *ibpkeycons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + struct in6_addr subnet_prefix; + + for (i = 0; i < ibpkeycons->count; i++) { + struct cil_ibpkeycon *cil_ibpkeycon = ibpkeycons->array[i]; + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBPKEY], &tail); + + rc = inet_pton(AF_INET6, cil_ibpkeycon->subnet_prefix_str, &subnet_prefix); + if (rc != 1) { + cil_log(CIL_ERR, "ibpkeycon subnet prefix not in valid IPV6 format\n"); + rc = SEPOL_ERR; + goto exit; + } + + memcpy(&new_ocon->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0], + sizeof(new_ocon->u.ibpkey.subnet_prefix)); + new_ocon->u.ibpkey.low_pkey = cil_ibpkeycon->pkey_low; + new_ocon->u.ibpkey.high_pkey = cil_ibpkeycon->pkey_high; + + rc = __cil_context_to_sepol_context(pdb, cil_ibpkeycon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < portcons->count; i++) { + struct cil_portcon *cil_portcon = portcons->array[i]; + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail); + + switch (cil_portcon->proto) { + case CIL_PROTOCOL_UDP: + new_ocon->u.port.protocol = IPPROTO_UDP; + break; + case CIL_PROTOCOL_TCP: + new_ocon->u.port.protocol = IPPROTO_TCP; + break; + case CIL_PROTOCOL_DCCP: + new_ocon->u.port.protocol = IPPROTO_DCCP; + break; + case CIL_PROTOCOL_SCTP: + new_ocon->u.port.protocol = IPPROTO_SCTP; + break; + default: + /* should not get here */ + rc = SEPOL_ERR; + goto exit; + } + + new_ocon->u.port.low_port = cil_portcon->port_low; + new_ocon->u.port.high_port = cil_portcon->port_high; + + rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < netifcons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail); + struct cil_netifcon *cil_netifcon = netifcons->array[i]; + + new_ocon->u.name = cil_strdup(cil_netifcon->interface_str); + + rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]); + if (rc != SEPOL_OK) { + context_destroy(&new_ocon->context[0]); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_ibendportcon_to_policydb(policydb_t *pdb, struct cil_sort *ibendportcons) +{ + int rc = SEPOL_ERR; + uint32_t i; + ocontext_t *tail = NULL; + + for (i = 0; i < ibendportcons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBENDPORT], &tail); + struct cil_ibendportcon *cil_ibendportcon = ibendportcons->array[i]; + + new_ocon->u.ibendport.dev_name = cil_strdup(cil_ibendportcon->dev_name_str); + new_ocon->u.ibendport.port = cil_ibendportcon->port; + + rc = __cil_context_to_sepol_context(pdb, cil_ibendportcon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + ocontext_t *tail6 = NULL; + + for (i = 0; i < nodecons->count; i++) { + ocontext_t *new_ocon = NULL; + struct cil_nodecon *cil_nodecon = nodecons->array[i]; + + if (cil_nodecon->addr->family == AF_INET) { + new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail); + new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr; + new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr; + } else if (cil_nodecon->addr->family == AF_INET6) { + new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6); + memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16); + memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16); + } else { + /* should not get here */ + rc = SEPOL_ERR; + goto exit; + } + + rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < fsuses->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail); + struct cil_fsuse *cil_fsuse = fsuses->array[i]; + + new_ocon->u.name = cil_strdup(cil_fsuse->fs_str); + new_ocon->v.behavior = cil_fsuse->type; + + rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + genfs_t *genfs_tail = NULL; + ocontext_t *ocon_tail = NULL; + + for (i = 0; i < genfscons->count; i++) { + struct cil_genfscon *cil_genfscon = genfscons->array[i]; + ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t)); + memset(new_ocon, 0, sizeof(ocontext_t)); + + if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) { + ocon_tail->next = new_ocon; + } else { + genfs_t *new_genfs = cil_malloc(sizeof(genfs_t)); + memset(new_genfs, 0, sizeof(genfs_t)); + new_genfs->fstype = cil_strdup(cil_genfscon->fs_str); + new_genfs->head = new_ocon; + + if (genfs_tail) { + genfs_tail->next = new_genfs; + } else { + pdb->genfs = new_genfs; + } + genfs_tail = new_genfs; + } + + ocon_tail = new_ocon; + + new_ocon->u.name = cil_strdup(cil_genfscon->path_str); + + if (cil_genfscon->file_type != CIL_FILECON_ANY) { + class_datum_t *class_datum; + const char *class_name; + switch (cil_genfscon->file_type) { + case CIL_FILECON_FILE: + class_name = "file"; + break; + case CIL_FILECON_DIR: + class_name = "dir"; + break; + case CIL_FILECON_CHAR: + class_name = "chr_file"; + break; + case CIL_FILECON_BLOCK: + class_name = "blk_file"; + break; + case CIL_FILECON_SOCKET: + class_name = "sock_file"; + break; + case CIL_FILECON_PIPE: + class_name = "fifo_file"; + break; + case CIL_FILECON_SYMLINK: + class_name = "lnk_file"; + break; + default: + rc = SEPOL_ERR; + goto exit; + } + class_datum = hashtab_search(pdb->p_classes.table, class_name); + if (!class_datum) { + rc = SEPOL_ERR; + goto exit; + } + new_ocon->v.sclass = class_datum->s.value; + } + + rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < pirqcons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail); + struct cil_pirqcon *cil_pirqcon = pirqcons->array[i]; + + new_ocon->u.pirq = cil_pirqcon->pirq; + + rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < iomemcons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail); + struct cil_iomemcon *cil_iomemcon = iomemcons->array[i]; + + new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low; + new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high; + + rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < ioportcons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail); + struct cil_ioportcon *cil_ioportcon = ioportcons->array[i]; + + new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low; + new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high; + + rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < pcidevicecons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail); + struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i]; + + new_ocon->u.device = cil_pcidevicecon->dev; + + rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < devicetreecons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail); + struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i]; + + new_ocon->u.name = cil_strdup(cil_devicetreecon->path); + + rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def) +{ + struct cil_list_item *curr; + class_datum_t *sepol_class; + struct cil_list *class_list = NULL; + + cil_list_for_each(curr, def->class_datums) { + struct cil_list_item *c; + + class_list = cil_expand_class(curr->data); + + cil_list_for_each(c, class_list) { + int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); + if (rc != SEPOL_OK) goto exit; + + switch (def->flavor) { + case CIL_DEFAULTUSER: + if (!sepol_class->default_user) { + sepol_class->default_user = def->object; + } else if (sepol_class->default_user != (char)def->object) { + cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn); + goto exit; + } + break; + case CIL_DEFAULTROLE: + if (!sepol_class->default_role) { + sepol_class->default_role = def->object; + } else if (sepol_class->default_role != (char)def->object) { + cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn); + goto exit; + } + break; + case CIL_DEFAULTTYPE: + if (!sepol_class->default_type) { + sepol_class->default_type = def->object; + } else if (sepol_class->default_type != (char)def->object) { + cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn); + goto exit; + } + break; + default: + goto exit; + } + } + + cil_list_destroy(&class_list, CIL_FALSE); + } + + return SEPOL_OK; + +exit: + cil_list_destroy(&class_list, CIL_FALSE); + return SEPOL_ERR; +} + +static int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def) +{ + struct cil_list_item *curr; + class_datum_t *sepol_class; + struct cil_list *class_list = NULL; + + cil_list_for_each(curr, def->class_datums) { + struct cil_list_item *c; + + class_list = cil_expand_class(curr->data); + + cil_list_for_each(c, class_list) { + int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); + if (rc != SEPOL_OK) goto exit; + + if (!sepol_class->default_range) { + sepol_class->default_range = def->object_range; + } else if (sepol_class->default_range != (char)def->object_range) { + cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn); + goto exit; + } + } + + cil_list_destroy(&class_list, CIL_FALSE); + } + + return SEPOL_OK; + +exit: + cil_list_destroy(&class_list, CIL_FALSE); + return SEPOL_ERR; +} + +static int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) +{ + int rc = SEPOL_OK; + int pass; + struct cil_args_binary *args = extra_args; + const struct cil_db *db; + policydb_t *pdb; + hashtab_t role_trans_table; + void **type_value_to_cil; + + db = args->db; + pdb = args->pdb; + pass = args->pass; + role_trans_table = args->role_trans_table; + type_value_to_cil = args->type_value_to_cil; + + if (node->flavor >= CIL_MIN_DECLARATIVE) { + if (node != NODE(node->data)) { + goto exit; + } + } + + switch (pass) { + case 1: + switch (node->flavor) { + case CIL_ROLE: + rc = cil_role_to_policydb(pdb, node->data); + break; + case CIL_TYPE: + rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil); + break; + case CIL_TYPEATTRIBUTE: + rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil); + break; + case CIL_POLICYCAP: + rc = cil_policycap_to_policydb(pdb, node->data); + break; + case CIL_USER: + rc = cil_user_to_policydb(pdb, node->data); + break; + case CIL_BOOL: + rc = cil_bool_to_policydb(pdb, node->data); + break; + case CIL_CATALIAS: + if (pdb->mls == CIL_TRUE) { + rc = cil_catalias_to_policydb(pdb, node->data); + } + break; + case CIL_SENS: + if (pdb->mls == CIL_TRUE) { + rc = cil_sepol_level_define(pdb, node->data); + } + break; + default: + break; + } + break; + case 2: + switch (node->flavor) { + case CIL_TYPE: + rc = cil_type_bounds_to_policydb(pdb, node->data); + break; + case CIL_TYPEALIAS: + rc = cil_typealias_to_policydb(pdb, node->data); + break; + case CIL_TYPEPERMISSIVE: + rc = cil_typepermissive_to_policydb(pdb, node->data); + break; + case CIL_TYPEATTRIBUTE: + rc = cil_typeattribute_to_bitmap(pdb, db, node->data); + break; + case CIL_SENSALIAS: + if (pdb->mls == CIL_TRUE) { + rc = cil_sensalias_to_policydb(pdb, node->data); + } + break; + case CIL_ROLE: + rc = cil_role_bounds_to_policydb(pdb, node->data); + if (rc != SEPOL_OK) goto exit; + rc = cil_roletype_to_policydb(pdb, db, node->data); + break; + case CIL_USER: + rc = cil_user_bounds_to_policydb(pdb, node->data); + if (rc != SEPOL_OK) goto exit; + if (pdb->mls == CIL_TRUE) { + rc = cil_userlevel_userrange_to_policydb(pdb, node->data); + if (rc != SEPOL_OK) { + goto exit; + } + } + rc = cil_userrole_to_policydb(pdb, db, node->data); + break; + case CIL_TYPE_RULE: + rc = cil_type_rule_to_policydb(pdb, db, node->data); + break; + case CIL_AVRULE: + case CIL_AVRULEX: { + struct cil_avrule *rule = node->data; + if (db->disable_neverallow != CIL_TRUE && rule->rule_kind == CIL_AVRULE_NEVERALLOW) { + struct cil_list *neverallows = args->neverallows; + cil_list_prepend(neverallows, CIL_LIST_ITEM, node); + } + break; + } + case CIL_ROLETRANSITION: + rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table); + break; + case CIL_ROLEATTRIBUTESET: + /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/ + break; + case CIL_NAMETYPETRANSITION: + rc = cil_typetransition_to_policydb(pdb, db, node->data); + break; + case CIL_CONSTRAIN: + rc = cil_constrain_to_policydb(pdb, db, node->data); + break; + case CIL_MLSCONSTRAIN: + if (pdb->mls == CIL_TRUE) { + rc = cil_constrain_to_policydb(pdb, db, node->data); + } + break; + case CIL_VALIDATETRANS: + rc = cil_validatetrans_to_policydb(pdb, db, node->data); + break; + case CIL_MLSVALIDATETRANS: + if (pdb->mls == CIL_TRUE) { + rc = cil_validatetrans_to_policydb(pdb, db, node->data); + } + break; + case CIL_RANGETRANSITION: + if (pdb->mls == CIL_TRUE) { + rc = cil_rangetransition_to_policydb(pdb, db, node->data); + } + break; + case CIL_DEFAULTUSER: + case CIL_DEFAULTROLE: + case CIL_DEFAULTTYPE: + rc = cil_default_to_policydb(pdb, node->data); + break; + case CIL_DEFAULTRANGE: + rc = cil_defaultrange_to_policydb(pdb, node->data); + break; + default: + break; + } + break; + case 3: + switch (node->flavor) { + case CIL_BOOLEANIF: + rc = cil_booleanif_to_policydb(pdb, db, node); + break; + case CIL_AVRULE: { + struct cil_avrule *rule = node->data; + if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { + rc = cil_avrule_to_policydb(pdb, db, node->data); + } + } + break; + case CIL_AVRULEX: { + struct cil_avrule *rule = node->data; + if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { + rc = cil_avrulex_to_hashtable(pdb, db, node->data, args); + } + } + break; + case CIL_ROLEALLOW: + rc = cil_roleallow_to_policydb(pdb, db, node->data); + break; + default: + break; + } + default: + break; + } + +exit: + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_ERR, "Binary policy creation failed"); + } + return rc; +} + +static int __cil_binary_create_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + + if (node->flavor == CIL_BLOCK) { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + rc = SEPOL_OK; + goto exit; + } + } else if (node->flavor == CIL_MACRO) { + *finished = CIL_TREE_SKIP_HEAD; + rc = SEPOL_OK; + goto exit; + } else if (node->flavor == CIL_BOOLEANIF) { + *finished = CIL_TREE_SKIP_HEAD; + } + + rc = __cil_node_to_policydb(node, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + +exit: + return rc; +} + +static int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db) +{ + int rc = SEPOL_ERR; + + rc = cil_portcon_to_policydb(pdb, db->portcon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_netifcon_to_policydb(pdb, db->netifcon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_nodecon_to_policydb(pdb, db->nodecon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_fsuse_to_policydb(pdb, db->fsuse); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_genfscon_to_policydb(pdb, db->genfscon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_ibpkeycon_to_policydb(pdb, db->ibpkeycon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_ibendportcon_to_policydb(pdb, db->ibendportcon); + if (rc != SEPOL_OK) { + goto exit; + } + + if (db->target_platform == SEPOL_TARGET_XEN) { + rc = cil_pirqcon_to_policydb(pdb, db->pirqcon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_iomemcon_to_policydb(pdb, db->iomemcon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_ioportcon_to_policydb(pdb, db->ioportcon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon); + if (rc != SEPOL_OK) { + goto exit; + } + } + return SEPOL_OK; +exit: + return rc; +} + +static int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + common_datum_t *common = (common_datum_t *)datum; + + if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) { + return -EINVAL; + } + pdb->p_common_val_to_name[common->s.value - 1] = (char *)key; + + return 0; +} + +static int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + class_datum_t *class = (class_datum_t *)datum; + + if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) { + return -EINVAL; + } + pdb->p_class_val_to_name[class->s.value - 1] = (char *)key; + pdb->class_val_to_struct[class->s.value - 1] = class; + + return 0; +} + +static int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + role_datum_t *role = (role_datum_t *)datum; + + if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) { + return -EINVAL; + } + pdb->p_role_val_to_name[role->s.value - 1] = (char *)key; + pdb->role_val_to_struct[role->s.value - 1] = role; + + return 0; +} + +static int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + type_datum_t *type = (type_datum_t *)datum; + + if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) { + return -EINVAL; + } + pdb->p_type_val_to_name[type->s.value - 1] = (char *)key; + pdb->type_val_to_struct[type->s.value - 1] = type; + + return 0; +} + +static int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + user_datum_t *user = (user_datum_t *)datum; + + if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) { + return -EINVAL; + } + pdb->p_user_val_to_name[user->s.value - 1] = (char *)key; + pdb->user_val_to_struct[user->s.value - 1] = user; + + return 0; +} + +static int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + cond_bool_datum_t *bool = (cond_bool_datum_t *)datum; + + if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) { + return -EINVAL; + } + pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key; + pdb->bool_val_to_struct[bool->s.value - 1] = bool; + + return 0; +} + +static int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + level_datum_t *level = (level_datum_t *)datum; + + if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) { + return -EINVAL; + } + pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key; + + return 0; +} + +static int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + policydb_t *pdb = data; + cat_datum_t *cat = (cat_datum_t *)datum; + + if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) { + return -EINVAL; + } + pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key; + + return 0; +} + +static int __cil_policydb_val_arrays_create(policydb_t *policydb) +{ + int rc = SEPOL_ERR; + + policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim); + rc = ksu_hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + + policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim); + policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim); + rc = ksu_hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + + policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim); + policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim); + rc = ksu_hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + + policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim); + policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim); + rc = ksu_hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + + policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim); + policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim); + rc = ksu_hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + + policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim); + policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim); + rc = ksu_hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + + policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim); + rc = ksu_hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + + policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim); + rc = ksu_hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb); + if (rc != SEPOL_OK) { + goto exit; + } + +exit: + return rc; +} + +static void __cil_set_conditional_state_and_flags(policydb_t *pdb) +{ + cond_node_t *cur; + + for (cur = pdb->cond_list; cur != NULL; cur = cur->next) { + int new_state; + cond_av_list_t *c; + + new_state = cond_evaluate_expr(pdb, cur->expr); + + cur->cur_state = new_state; + + if (new_state == -1) { + cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n"); + } + + for (c = cur->true_list; c != NULL; c = c->next) { + if (new_state <= 0) { + c->node->key.specified &= ~AVTAB_ENABLED; + } else { + c->node->key.specified |= AVTAB_ENABLED; + } + } + + for (c = cur->false_list; c != NULL; c = c->next) { + if (new_state) { /* -1 or 1 */ + c->node->key.specified &= ~AVTAB_ENABLED; + } else { + c->node->key.specified |= AVTAB_ENABLED; + } + } + } +} + +static int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb) +{ + int rc; + struct policydb *pdb = NULL; + + rc = sepol_policydb_create(spdb); + if (rc < 0) { + cil_log(CIL_ERR, "Failed to create policy db\n"); + // spdb could be a dangling pointer at this point, so reset it so + // callers of this function don't need to worry about freeing garbage + *spdb = NULL; + goto exit; + } + + pdb = &(*spdb)->p; + + pdb->policy_type = POLICY_KERN; + pdb->target_platform = db->target_platform; + pdb->policyvers = db->policy_version; + pdb->handle_unknown = db->handle_unknown; + pdb->mls = db->mls; + + return SEPOL_OK; + +exit: + return rc; +} + + +static int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) +{ + int rc = SEPOL_ERR; + + // these flags should get set in __cil_policydb_create. However, for + // backwards compatibility, it is possible that __cil_policydb_create is + // never called. So, they must also be set here. + pdb->handle_unknown = db->handle_unknown; + pdb->mls = db->mls; + + rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil); + if (rc != SEPOL_OK) { + goto exit; + } + + if (pdb->mls == CIL_TRUE) { + rc = cil_catorder_to_policydb(pdb, db); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_sensitivityorder_to_policydb(pdb, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + + rc = ksu_avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = ksu_avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + + return rc; +} + +static unsigned int role_trans_hash(hashtab_t h, const_hashtab_key_t key) +{ + const role_trans_t *k = (const role_trans_t *)key; + return ((k->role + (k->type << 2) + + (k->tclass << 5)) & (h->size - 1)); +} + +static int role_trans_compare(hashtab_t h + __attribute__ ((unused)), const_hashtab_key_t key1, + const_hashtab_key_t key2) +{ + const role_trans_t *a = (const role_trans_t *)key1; + const role_trans_t *b = (const role_trans_t *)key2; + + return a->role != b->role || a->type != b->type || a->tclass != b->tclass; +} + +/* Based on MurmurHash3, written by Austin Appleby and placed in the + * public domain. + */ +static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hashtab_key_t key) +{ + const avtab_key_t *k = (const avtab_key_t *)key; + + static const uint32_t c1 = 0xcc9e2d51; + static const uint32_t c2 = 0x1b873593; + static const uint32_t r1 = 15; + static const uint32_t r2 = 13; + static const uint32_t m = 5; + static const uint32_t n = 0xe6546b64; + + uint32_t hash = 0; + +#define mix(input) do { \ + uint32_t v = input; \ + v *= c1; \ + v = (v << r1) | (v >> (32 - r1)); \ + v *= c2; \ + hash ^= v; \ + hash = (hash << r2) | (hash >> (32 - r2)); \ + hash = hash * m + n; \ +} while (0) + + mix(k->target_class); + mix(k->target_type); + mix(k->source_type); + mix(k->specified); + +#undef mix + + hash ^= hash >> 16; + hash *= 0x85ebca6b; + hash ^= hash >> 13; + hash *= 0xc2b2ae35; + hash ^= hash >> 16; + + return hash & (AVRULEX_TABLE_SIZE - 1); +} + +static int avrulex_compare(hashtab_t h + __attribute__ ((unused)), const_hashtab_key_t key1, + const_hashtab_key_t key2) +{ + const avtab_key_t *a = (const avtab_key_t *)key1; + const avtab_key_t *b = (const avtab_key_t *)key2; + + return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class || a->specified != b->specified; +} + +int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb) +{ + int rc = SEPOL_ERR; + struct sepol_policydb *pdb = NULL; + + rc = __cil_policydb_create(db, &pdb); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_binary_create_allocated_pdb(db, pdb); + if (rc != SEPOL_OK) { + goto exit; + } + + *policydb = pdb; + + return SEPOL_OK; + +exit: + sepol_policydb_free(pdb); + + return rc; +} + +static void __cil_destroy_sepol_class_perms(class_perm_node_t *curr) +{ + class_perm_node_t *next; + + while (curr) { + next = curr->next; + free(curr); + curr = next; + } +} + +static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *classperms, class_perm_node_t **sepol_class_perms) +{ + int rc = SEPOL_ERR; + struct cil_list_item *i; + cil_list_for_each(i, classperms) { + if (i->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = i->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + class_perm_node_t *cpn = NULL; + class_datum_t *sepol_class = NULL; + uint32_t data = 0; + + rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_perms_to_datum(cp->perms, sepol_class, &data); + if (rc != SEPOL_OK) goto exit; + if (data != 0) { /* Only add if there are permissions */ + cpn = cil_malloc(sizeof(class_perm_node_t)); + cpn->tclass = sepol_class->s.value; + cpn->data = data; + cpn->next = *sepol_class_perms; + *sepol_class_perms = cpn; + } + } else { /* MAP */ + struct cil_list_item *j = NULL; + cil_list_for_each(j, cp->perms) { + struct cil_perm *cmp = j->data; + rc = __cil_rule_to_sepol_class_perms(pdb, cmp->classperms, sepol_class_perms); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = i->data; + struct cil_classpermission *cp = cp_set->set; + rc = __cil_rule_to_sepol_class_perms(pdb, cp->classperms, sepol_class_perms); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissionx *permx, class_perm_node_t **sepol_class_perms) +{ + int rc = SEPOL_OK; + struct cil_list *class_list = NULL; + struct cil_list_item *c; + class_datum_t *sepol_obj = NULL; + class_perm_node_t *cpn; + uint32_t data = 0; + char *perm_str = NULL; + + class_list = cil_expand_class(permx->obj); + + cil_list_for_each(c, class_list) { + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); + if (rc != SEPOL_OK) { + goto exit; + } + + switch (permx->kind) { + case CIL_PERMX_KIND_IOCTL: + perm_str = CIL_KEY_IOCTL; + break; + default: + rc = SEPOL_ERR; + goto exit; + } + + rc = __perm_str_to_datum(perm_str, sepol_obj, &data); + if (rc != SEPOL_OK) { + goto exit; + } + + cpn = cil_malloc(sizeof(*cpn)); + cpn->tclass = sepol_obj->s.value; + cpn->data = data; + cpn->next = *sepol_class_perms; + *sepol_class_perms = cpn; + } + +exit: + cil_list_destroy(&class_list, CIL_FALSE); + + return rc; +} + +static void __cil_init_sepol_type_set(type_set_t *t) +{ + ebitmap_init(&t->types); + ebitmap_init(&t->negset); + t->flags = 0; +} + +static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *n = NODE(datum); + type_datum_t *sepol_datum = NULL; + + if (n->flavor == CIL_TYPEATTRIBUTE) { + ebitmap_node_t *tnode; + unsigned int i; + struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; + ebitmap_for_each_positive_bit(attr->types, tnode, i) { + datum = DATUM(db->val_to_type[i]); + rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum); + if (rc != SEPOL_OK) goto exit; + ksu_ebitmap_set_bit(map, sepol_datum->s.value - 1, 1); + } + } else { + rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum); + if (rc != SEPOL_OK) goto exit; + ksu_ebitmap_set_bit(map, sepol_datum->s.value - 1, 1); + } + + return SEPOL_OK; + +exit: + return rc; +} + +static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node) +{ + avrule_t *avrule; + struct cil_tree_node *source_node; + char *source_path; + char *lm_kind; + uint32_t hll_line; + + avrule = cil_malloc(sizeof(avrule_t)); + avrule->specified = kind; + avrule->flags = 0; + __cil_init_sepol_type_set(&avrule->stypes); + __cil_init_sepol_type_set(&avrule->ttypes); + avrule->perms = NULL; + avrule->line = node->line; + + avrule->source_filename = NULL; + avrule->source_line = node->line; + source_node = cil_tree_get_next_path(node, &lm_kind, &hll_line, &source_path); + if (source_node) { + avrule->source_filename = source_path; + if (lm_kind != CIL_KEY_SRC_CIL) { + avrule->source_line = hll_line + node->hll_offset - source_node->hll_offset - 1; + } + } + + avrule->next = NULL; + return avrule; +} + +static void __cil_destroy_sepol_avrules(avrule_t *curr) +{ + avrule_t *next; + + while (curr) { + next = curr->next; + ksu_ebitmap_destroy(&curr->stypes.types); + ksu_ebitmap_destroy(&curr->stypes.negset); + ksu_ebitmap_destroy(&curr->ttypes.types); + ksu_ebitmap_destroy(&curr->ttypes.negset); + __cil_destroy_sepol_class_perms(curr->perms); + free(curr); + curr = next; + } +} + +static void __cil_print_parents(const char *pad, struct cil_tree_node *n) +{ + if (!n) return; + + __cil_print_parents(pad, n->parent); + + if (n->flavor != CIL_SRC_INFO) { + cil_tree_log(n, CIL_ERR,"%s%s", pad, cil_node_to_string(n)); + } +} + +static void __cil_print_classperm(struct cil_list *cp_list) +{ + struct cil_list_item *i1, *i2; + + i1 = cp_list->head; + if (i1->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = i1->data; + cil_log(CIL_ERR,"(%s (", DATUM(cp->class)->fqn); + cil_list_for_each(i2, cp->perms) { + cil_log(CIL_ERR,"%s",DATUM(i2->data)->fqn); + if (i2 != cp->perms->tail) { + cil_log(CIL_ERR," "); + } else { + cil_log(CIL_ERR,"))"); + } + } + } else { + struct cil_classperms_set *cp_set = i1->data; + cil_log(CIL_ERR,"%s", DATUM(cp_set->set)->fqn); + } +} + +static void __cil_print_permissionx(struct cil_permissionx *px) +{ + const char *kind_str = ""; + char *expr_str; + + switch (px->kind) { + case CIL_PERMX_KIND_IOCTL: + kind_str = CIL_KEY_IOCTL; + break; + default: + kind_str = "unknown"; + break; + } + + __cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str); + + cil_log(CIL_ERR, "%s %s (%s)", kind_str, DATUM(px->obj)->fqn, expr_str); + + free(expr_str); +} + +static void __cil_print_rule(const char *pad, const char *kind, struct cil_avrule *avrule) +{ + cil_log(CIL_ERR,"%s(%s ", pad, kind); + cil_log(CIL_ERR,"%s %s ", DATUM(avrule->src)->fqn, DATUM(avrule->tgt)->fqn); + + if (!avrule->is_extended) { + __cil_print_classperm(avrule->perms.classperms); + } else { + cil_log(CIL_ERR, "("); + __cil_print_permissionx(avrule->perms.x.permx); + cil_log(CIL_ERR, ")"); + } + + cil_log(CIL_ERR,")\n"); +} + +static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tree_node *node) +{ + int rc; + struct cil_list_item *i2; + struct cil_list *matching; + struct cil_avrule *cil_rule = node->data; + struct cil_avrule target; + struct cil_tree_node *n2; + struct cil_avrule *r2; + char *neverallow_str; + char *allow_str; + enum cil_flavor avrule_flavor; + int num_matching = 0; + int count_matching = 0; + enum cil_log_level log_level = cil_get_log_level(); + + target.rule_kind = CIL_AVRULE_ALLOWED; + target.is_extended = cil_rule->is_extended; + target.src = cil_rule->src; + target.tgt = cil_rule->tgt; + target.perms = cil_rule->perms; + + if (!cil_rule->is_extended) { + neverallow_str = CIL_KEY_NEVERALLOW; + allow_str = CIL_KEY_ALLOW; + avrule_flavor = CIL_AVRULE; + } else { + neverallow_str = CIL_KEY_NEVERALLOWX; + allow_str = CIL_KEY_ALLOWX; + avrule_flavor = CIL_AVRULEX; + } + cil_tree_log(node, CIL_ERR, "%s check failed", neverallow_str); + __cil_print_rule(" ", neverallow_str, cil_rule); + cil_list_init(&matching, CIL_NODE); + rc = cil_find_matching_avrule_in_ast(db->ast->root, avrule_flavor, &target, matching, CIL_FALSE); + if (rc) { + cil_log(CIL_ERR, "Error occurred while checking %s rules\n", neverallow_str); + cil_list_destroy(&matching, CIL_FALSE); + goto exit; + } + + cil_list_for_each(i2, matching) { + num_matching++; + } + cil_list_for_each(i2, matching) { + n2 = i2->data; + r2 = n2->data; + __cil_print_parents(" ", n2); + __cil_print_rule(" ", allow_str, r2); + count_matching++; + if (count_matching >= 4 && num_matching > 4 && log_level == CIL_ERR) { + cil_log(CIL_ERR, " Only first 4 of %d matching rules shown (use \"-v\" to show all)\n", num_matching); + break; + } + } + cil_log(CIL_ERR,"\n"); + cil_list_destroy(&matching, CIL_FALSE); + +exit: + return rc; +} + +static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation) +{ + int rc = SEPOL_OK; + struct cil_avrule *cil_rule = node->data; + struct cil_symtab_datum *tgt = cil_rule->tgt; + uint32_t kind; + avrule_t *rule; + struct cil_list *xperms = NULL; + struct cil_list_item *item; + + if (!cil_rule->is_extended) { + kind = AVRULE_NEVERALLOW; + } else { + kind = AVRULE_XPERMS_NEVERALLOW; + } + + rule = __cil_init_sepol_avrule(kind, node); + rule->next = NULL; + + rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->stypes.types); + if (rc != SEPOL_OK) { + goto exit; + } + + if (tgt->fqn == CIL_KEY_SELF) { + rule->flags = RULE_SELF; + } else { + rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (!cil_rule->is_extended) { + rc = __cil_rule_to_sepol_class_perms(pdb, cil_rule->perms.classperms, &rule->perms); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = check_assertion(pdb, rule); + if (rc == CIL_TRUE) { + *violation = CIL_TRUE; + rc = __cil_print_neverallow_failure(db, node); + if (rc != SEPOL_OK) { + goto exit; + } + } + + } else { + rc = __cil_permx_to_sepol_class_perms(pdb, cil_rule->perms.x.permx, &rule->perms); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_list_for_each(item, xperms) { + rule->xperms = item->data; + rc = check_assertion(pdb, rule); + if (rc == CIL_TRUE) { + *violation = CIL_TRUE; + rc = __cil_print_neverallow_failure(db, node); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + } + +exit: + if (xperms != NULL) { + cil_list_for_each(item, xperms) { + free(item->data); + item->data = NULL; + } + cil_list_destroy(&xperms, CIL_FALSE); + } + + rule->xperms = NULL; + __cil_destroy_sepol_avrules(rule); + + return rc; +} + +static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation) +{ + int rc = SEPOL_OK; + struct cil_list_item *item; + + cil_list_for_each(item, neverallows) { + rc = cil_check_neverallow(db, pdb, item->data, violation); + if (rc != SEPOL_OK) { + goto exit; + } + } + +exit: + return rc; +} + +static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) +{ + struct cil_classperms *cp; + struct cil_list *cp_list; + class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1]; + unsigned i; + + cil_classperms_init(&cp); + + cp->class = class_value_to_cil[class]; + if (!cp->class) goto exit; + + cil_list_init(&cp->perms, CIL_PERM); + for (i = 0; i < sepol_class->permissions.nprim; i++) { + struct cil_perm *perm; + if ((data & (UINT32_C(1) << i)) == 0) continue; + perm = perm_value_to_cil[class][i+1]; + if (!perm) goto exit; + cil_list_append(cp->perms, CIL_PERM, perm); + } + + cil_list_init(&cp_list, CIL_CLASSPERMS); + cil_list_append(cp_list, CIL_CLASSPERMS, cp); + + return cp_list; + +exit: + cil_destroy_classperms(cp); + cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n"); + return NULL; +} + +static int cil_avrule_from_sepol(policydb_t *pdb, avtab_ptr_t sepol_rule, struct cil_avrule *cil_rule, void *type_value_to_cil[], struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) +{ + int rc = SEPOL_ERR; + avtab_key_t *k = &sepol_rule->key; + avtab_datum_t *d = &sepol_rule->datum; + cil_rule->src = type_value_to_cil[k->source_type]; + if (!cil_rule->src) goto exit; + + cil_rule->tgt = type_value_to_cil[k->target_type]; + if (!cil_rule->tgt) goto exit; + + cil_rule->perms.classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil); + if (!cil_rule->perms.classperms) goto exit; + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n"); + return rc; +} + +static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[], int *violation) +{ + int rc = SEPOL_OK; + int i; + + for (i = 0; i < db->num_types; i++) { + type_datum_t *child; + type_datum_t *parent; + avtab_ptr_t bad = NULL; + int numbad = 0; + struct cil_type *t = db->val_to_type[i]; + + if (!t->bounds) continue; + + rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child); + if (rc != SEPOL_OK) goto exit; + + rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent); + if (rc != SEPOL_OK) goto exit; + + rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad); + if (rc != SEPOL_OK) goto exit; + + if (bad) { + avtab_ptr_t cur; + struct cil_avrule target; + struct cil_tree_node *n1 = NULL; + int count_bad = 0; + enum cil_log_level log_level = cil_get_log_level(); + + *violation = CIL_TRUE; + + target.is_extended = 0; + target.rule_kind = CIL_AVRULE_ALLOWED; + target.src_str = NULL; + target.tgt_str = NULL; + + cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n", + t->datum.fqn, t->bounds->datum.fqn); + for (cur = bad; cur; cur = cur->next) { + struct cil_list_item *i2; + struct cil_list *matching; + int num_matching = 0; + int count_matching = 0; + + rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n"); + bounds_destroy_bad(bad); + goto exit; + } + __cil_print_rule(" ", "allow", &target); + cil_list_init(&matching, CIL_NODE); + rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE); + if (rc) { + cil_log(CIL_ERR, "Error occurred while checking type bounds\n"); + cil_list_destroy(&matching, CIL_FALSE); + cil_list_destroy(&target.perms.classperms, CIL_TRUE); + bounds_destroy_bad(bad); + goto exit; + } + cil_list_for_each(i2, matching) { + num_matching++; + } + cil_list_for_each(i2, matching) { + struct cil_tree_node *n2 = i2->data; + struct cil_avrule *r2 = n2->data; + if (n1 == n2) { + cil_log(CIL_ERR, " \n"); + } else { + n1 = n2; + __cil_print_parents(" ", n2); + __cil_print_rule(" ", "allow", r2); + } + count_matching++; + if (count_matching >= 2 && num_matching > 2 && log_level == CIL_ERR) { + cil_log(CIL_ERR, " Only first 2 of %d matching rules shown (use \"-v\" to show all)\n", num_matching); + break; + } + } + cil_list_destroy(&matching, CIL_FALSE); + cil_list_destroy(&target.perms.classperms, CIL_TRUE); + count_bad++; + if (count_bad >= 4 && numbad > 4 && log_level == CIL_ERR) { + cil_log(CIL_ERR, " Only first 4 of %d bad rules shown (use \"-v\" to show all)\n", numbad); + break; + } + } + bounds_destroy_bad(bad); + } + } + +exit: + return rc; +} + +// assumes policydb is already allocated and initialized properly with things +// like policy type set to kernel and version set appropriately +int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb) +{ + int rc = SEPOL_ERR; + int i; + struct cil_args_binary extra_args; + policydb_t *pdb = &policydb->p; + struct cil_list *neverallows = NULL; + hashtab_t role_trans_table = NULL; + hashtab_t avrulex_ioctl_table = NULL; + void **type_value_to_cil = NULL; + struct cil_class **class_value_to_cil = NULL; + struct cil_perm ***perm_value_to_cil = NULL; + + if (db == NULL || policydb == NULL) { + if (db == NULL) { + cil_log(CIL_ERR,"db == NULL\n"); + } else if (policydb == NULL) { + cil_log(CIL_ERR,"policydb == NULL\n"); + } + return SEPOL_ERR; + } + + /* libsepol values start at 1. Just allocate extra memory rather than + * subtract 1 from the sepol value. + */ + type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil)); + if (!type_value_to_cil) goto exit; + + class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil)); + if (!class_value_to_cil) goto exit; + + perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil)); + if (!perm_value_to_cil) goto exit; + for (i=1; i < db->num_classes+1; i++) { + perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i])); + if (!perm_value_to_cil[i]) goto exit; + } + + rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR,"Problem in policydb_init\n"); + goto exit; + } + + role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE); + if (!role_trans_table) { + cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n"); + goto exit; + } + + avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); + if (!avrulex_ioctl_table) { + cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); + goto exit; + } + + cil_list_init(&neverallows, CIL_LIST_ITEM); + + extra_args.db = db; + extra_args.pdb = pdb; + extra_args.neverallows = neverallows; + extra_args.role_trans_table = role_trans_table; + extra_args.avrulex_ioctl_table = avrulex_ioctl_table; + extra_args.type_value_to_cil = type_value_to_cil; + + for (i = 1; i <= 3; i++) { + extra_args.pass = i; + + rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure while walking cil database\n"); + goto exit; + } + + if (i == 1) { + rc = __cil_policydb_val_arrays_create(pdb); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n"); + goto exit; + } + } + + if (i == 3) { + rc = ksu_hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure creating avrulex rules\n"); + goto exit; + } + } + } + + rc = cil_sidorder_to_policydb(pdb, db); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_contexts_to_policydb(pdb, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n"); + goto exit; + } + + if (pdb->type_attr_map == NULL) { + rc = __cil_typeattr_bitmap_init(pdb); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n"); + goto exit; + } + } + + cond_optimize_lists(pdb->cond_list); + __cil_set_conditional_state_and_flags(pdb); + + if (db->disable_neverallow != CIL_TRUE) { + int violation = CIL_FALSE; + cil_log(CIL_INFO, "Checking Neverallows\n"); + rc = cil_check_neverallows(db, pdb, neverallows, &violation); + if (rc != SEPOL_OK) goto exit; + + cil_log(CIL_INFO, "Checking User Bounds\n"); + rc = bounds_check_users(NULL, pdb); + if (rc) { + violation = CIL_TRUE; + } + + cil_log(CIL_INFO, "Checking Role Bounds\n"); + rc = bounds_check_roles(NULL, pdb); + if (rc) { + violation = CIL_TRUE; + } + + cil_log(CIL_INFO, "Checking Type Bounds\n"); + rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation); + if (rc != SEPOL_OK) goto exit; + + if (violation == CIL_TRUE) { + rc = SEPOL_ERR; + goto exit; + } + + } + + /* This pre-expands the roles and users for context validity checking */ + if (ksu_hashtab_map(pdb->p_roles.table, policydb_role_cache, pdb)) { + cil_log(CIL_INFO, "Failure creating roles cache"); + rc = SEPOL_ERR; + goto exit; + } + + if (ksu_hashtab_map(pdb->p_users.table, policydb_user_cache, pdb)) { + cil_log(CIL_INFO, "Failure creating users cache"); + rc = SEPOL_ERR; + goto exit; + } + + rc = SEPOL_OK; + +exit: + ksu_hashtab_destroy(role_trans_table); + ksu_hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL); + ksu_hashtab_destroy(avrulex_ioctl_table); + free(type_value_to_cil); + free(class_value_to_cil); + if (perm_value_to_cil != NULL) { + /* Range is because libsepol values start at 1. */ + for (i=1; i < db->num_classes+1; i++) { + free(perm_value_to_cil[i]); + } + free(perm_value_to_cil); + } + cil_list_destroy(&neverallows, CIL_FALSE); + + return rc; +} diff --git a/kernel/libsepol/cil/src/cil_binary.h b/kernel/libsepol/cil/src/cil_binary.h new file mode 100644 index 00000000..0b6e3b79 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_binary.h @@ -0,0 +1,477 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef _CIL_BINARY_H_ +#define _CIL_BINARY_H_ + +#include + +#include "cil_internal.h" +#include "cil_tree.h" +#include "cil_list.h" + +/** + * Create a binary policydb from the cil db. + * + * @param[in] db The cil database. + * @param[in] pdb The policy database. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_binary_create(const struct cil_db *db, sepol_policydb_t **pdb); + +/** + * Create a pre allocated binary policydb from the cil db. + * + * It is assumed that pdb has been allocated and initialized so that fields such + * as policy type and version are set appropriately. It is recommended that + * instead of calling this, one instead calls cil_binary_create, which will + * properly allocate and initialize the pdb and then calls this function. This + * function is used to maintain binary backwards compatibility. + * + * @param[in] db The cil database. + * @param[in] pdb The policy database. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *pdb); + +/** + * Insert cil common structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the common into. + * @param[in] datum The cil_common datum. + * @param[out] common_out The sepol common to send back. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_common_to_policydb(policydb_t *pdb, struct cil_class *cil_common, common_datum_t **common_out); + +/** + * Insert cil class structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the class into. + * @param[in] datum The cil_class datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_class_to_policydb(policydb_t *pdb, struct cil_class *cil_class); + +/** + * Insert cil role structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the role into. + * @param[in] datum The cil_role datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_role_to_policydb(policydb_t *pdb, struct cil_role *cil_role); + +/** + * Insert cil roletype structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the roletype into. + * @param[in] db The cil database + * @param[in] datum The cil_roletype datum. + * + * @return SEPOL_OK upon success or SEPOL_ERR otherwise. + */ +int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_role *role); + +/** + * Insert cil type structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the type into. + * @param[in] datum The cil_type datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[]); + +/** + * Insert cil typealias structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the typealias into. + * @param[in] datum The cil_typealias datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias); + +/** + * Insert cil typepermissive structure into sepol policydb. + * The function looks up the previously inserted type and flips the bit + * in the permssive types bitmap that corresponds to that type's value. + * + * @param[in] pdb The policy database to insert the typepermissive into. + * @param[in] datum The cil_typepermissive datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm); + +/** + * Insert cil attribute structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the attribute into. + * @param[in] datum The cil_attribute datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[]); + +/** + * Insert cil attribute structure into sepol type->attribute bitmap. + * The function calls helper functions to loop over the attributes lists + * of types and negative types. If either of the lists contain an attribute, + * the helper functions will recurse into the attribute and record the + * attribute's types and negative types. There is no minimum depth. + * + * @param[in] pdb The policy database that contains the type->attribute bitmap. + * @param[in] db The cil database + * @param[in] node The tree node that contains the cil_attribute. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *cdb, struct cil_typeattribute *cil_attr); + +/** + * Insert cil policycap structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the policycap into. + * @param[in] node The tree node that contains the cil_policycap. + * + * @return SEPOL_OK upon success or SEPOL_ERR upon error. + */ +int cil_policycap_to_policydb(policydb_t *pdb, struct cil_policycap *cil_polcap); + +/** + * Insert cil user structure into sepol policydb. + * + * @param[in] pdb THe policy database to insert the user into. + * @param[in] node The tree node that contains the cil_user. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user); + +/** + * Insert cil userrole structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the userrole into. + * @param[in] db The cil database + * @param[in] datum The cil_user + * + * @return SEPOL_OK upon success or SEPOL_ERR otherwise. + */ +int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user); + +/** + * Insert cil bool structure into sepol policydb. + * + * @param[in] pdb THe policy database to insert the bool into. + * @param[in] datum The cil_bool datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_bool_to_policydb(policydb_t *pdb, struct cil_bool *cil_bool); + +/** + * Insert all ordered cil category structures into sepol policydb. + * + * @param[in] pdb The policy database to insert the categories into. + * @param[in] db The cil database that contains the category order list. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_catorder_to_policydb(policydb_t *pdb, const struct cil_db *db); + +/** + * Insert cil category alias structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the category alias into. + * @param[in] datum The cil_catalias datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias); + +/** + * Insert the cil sensitivityorder into sepol policydb. + * + * @param[in] pdb The policy database to insert the sensitivityorder into. + * @param[in] db the cil database that contains the sensitivityorder list. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_sensitivityorder_to_policydb(policydb_t *pdb, const struct cil_db *db); + +/** + * Insert cil type rule structure into sepol policydb. This includes + * typetransition, typechange, and typemember. + * + * @param[in] pdb The policy database to insert the type rule into. + * @param[in] datum The cil_type_rule datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule); + +/** + * Insert cil avrule structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the avrule into. + * @param[in] datum The cil_avrule datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule); + +/** + * Insert cil booleanif structure into sepol policydb. This populates the + * policydb conditional list. Each conditional node contains an expression + * and true/false avtab_ptr lists that point into te_cond_avtab. + * + * @param[in] pdb The policy database to insert the booleanif into. + * @param[in] node The cil_booleanif node. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node); + +/** + * Insert cil role transition structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the role transition into. + * @param[in] datum The cil_role_trans datum. + * + * @return SEPOL_OK upon success or SEPOL_ERR upon error. + */ +int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table); + +/** + * Insert cil role allow structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the role allow into. + * @param[in] datum The cil_role_allow datum. + * + * @return SEPOL_OK upon success or SEPOL_ERR upon error. + */ +int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow); + +/** + * Insert cil file transition structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the file transition into. + * @param[in] datum The cil_nametypetransition datum. + * + * @return SEPOL_OK upon success or SEPOL_ERR upon error. + */ +int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans); + +/** + * Insert cil constrain/mlsconstrain structure(s) into sepol policydb. + * + * @param[in] pdb The policy database to insert the (mls)constrain into. + * @param[in] datum The cil_(mls)constrain datum. + * + * @return SEPOL_OK upon success or SEPOL_ERR upon error. + */ +int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain); + +/** + * Define sepol level. + * Associates the sepol level (sensitivity) with categories. + * Looks at the cil_sens structure for a list of cil_cats to + * associate the sensitivity with. + * Sets the sepol level as defined in the sepol policy database. + * + * @param[in] pdb The policy database that holds the sepol level. + * @param[in] datum The cil_sens datum. + * + * @return SEPOL_OK upon success or SEPOL_ERR upon error. + */ +int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens); + +/** + * Insert cil rangetransition structure into sepol policydb. + * + * @param[in] pdb The policy database to insert the rangetransition into. + * @param[in] datum The cil_rangetransition datum. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans); + +/** + * Insert cil ibpkeycon structure into sepol policydb. + * The function is given a structure containing the sorted ibpkeycons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the ibpkeycon into. + * @param[in] node The cil_sort structure that contains the sorted ibpkeycons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_ibpkeycon_to_policydb(policydb_t *pdb, struct cil_sort *ibpkeycons); + +/** + * Insert cil idbev structure into sepol policydb. + * The function is given a structure containing the sorted ibendportcons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the pkeycon into. + * @param[in] node The cil_sort structure that contains the sorted ibendportcons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_ibendportcon_to_policydb(policydb_t *pdb, struct cil_sort *pkeycons); + +/** + * Insert cil portcon structure into sepol policydb. + * The function is given a structure containing the sorted portcons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the portcon into. + * @param[in] node The cil_sort structure that contains the sorted portcons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons); + +/** + * Insert cil netifcon structure into sepol policydb. + * The function is given a structure containing the sorted netifcons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the netifcon into. + * @param[in] node The cil_sort structure that contains the sorted netifcons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons); + +/** + * Insert cil nodecon structure into sepol policydb. + * The function is given a structure containing the sorted nodecons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the nodecon into. + * @param[in] node The cil_sort structure that contains the sorted nodecons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons); + +/** + * Insert cil fsuse structure into sepol policydb. + * The function is given a structure containing the sorted fsuses and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the fsuse into. + * @param[in] node The cil_sort structure that contains the sorted fsuses. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses); + +/** + * Insert cil genfscon structure into sepol policydb. + * The function is given a structure containing the sorted genfscons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the genfscon into. + * @param[in] node The cil_sort structure that contains the sorted genfscons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons); + +/** + * Insert cil pirqcon structure into sepol policydb. + * The function is given a structure containing the sorted pirqcons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the pirqcon into. + * @param[in] node The cil_sort structure that contains the sorted pirqcons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons); + +/** + * Insert cil iomemcon structure into sepol policydb. + * The function is given a structure containing the sorted iomemcons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the iomemcon into. + * @param[in] node The cil_sort structure that contains the sorted iomemcons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons); + +/** + * Insert cil ioportcon structure into sepol policydb. + * The function is given a structure containing the sorted ioportcons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the ioportcon into. + * @param[in] node The cil_sort structure that contains the sorted ioportcons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons); + +/** + * Insert cil pcidevicecon structure into sepol policydb. + * The function is given a structure containing the sorted pcidevicecons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the pcidevicecon into. + * @param[in] node The cil_sort structure that contains the sorted pcidevicecons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons); + +/** + * Create an mls level using a cil level. + * The function is given a structure containing the a cil_level and + * outputs a created mls_level_t. + * + * @param[in] pdb The policy database to use to get sepol level from cil_level's sensitivity. + * @param[in] cil_level The cil_level that will be used to create an mls_level_t. + * @param[out] mls_level The mls_level that is created. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level); + +#endif //_CIL_BINARY_H_ diff --git a/kernel/libsepol/cil/src/cil_build_ast.c b/kernel/libsepol/cil/src/cil_build_ast.c new file mode 100644 index 00000000..d7045556 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_build_ast.c @@ -0,0 +1,6623 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include + +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_parser.h" +#include "cil_build_ast.h" +#include "cil_copy_ast.h" +#include "cil_verify.h" +#include "cil_strpool.h" + +struct cil_args_build { + struct cil_tree_node *ast; + struct cil_db *db; + struct cil_tree_node *tunif; + struct cil_tree_node *in; + struct cil_tree_node *macro; + struct cil_tree_node *optional; + struct cil_tree_node *boolif; +}; + +static int cil_fill_list(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **list) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *curr; + enum cil_syntax syntax[] = { + CIL_SYN_N_STRINGS, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + rc = __cil_verify_syntax(current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_list_init(list, flavor); + + for (curr = current; curr != NULL; curr = curr->next) { + cil_list_append(*list, CIL_STRING, curr->data); + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_allow_multiple_decls(struct cil_db *db, enum cil_flavor f_new, enum cil_flavor f_old) +{ + if (f_new != f_old) { + return CIL_FALSE; + } + + switch (f_new) { + case CIL_TYPE: + case CIL_TYPEATTRIBUTE: + if (db->multiple_decls) { + return CIL_TRUE; + } + break; + case CIL_OPTIONAL: + return CIL_TRUE; + break; + default: + break; + } + + return CIL_FALSE; +} + +int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node) +{ + int rc; + + if (symtab == NULL || datum == NULL || node == NULL) { + return SEPOL_ERR; + } + + rc = cil_symtab_insert(symtab, key, datum, node); + if (rc == SEPOL_EEXIST) { + struct cil_symtab_datum *prev; + rc = cil_symtab_get_datum(symtab, key, &prev); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Re-declaration of %s %s, but previous declaration could not be found\n",cil_node_to_string(node), key); + return SEPOL_ERR; + } + if (!cil_allow_multiple_decls(db, node->flavor, FLAVOR(prev))) { + /* multiple_decls not ok, ret error */ + struct cil_tree_node *n = NODE(prev); + cil_log(CIL_ERR, "Re-declaration of %s %s\n", + cil_node_to_string(node), key); + cil_tree_log(node, CIL_ERR, "Previous declaration of %s", + cil_node_to_string(n)); + return SEPOL_ERR; + } + /* multiple_decls is enabled and works for this datum type, add node */ + cil_list_append(prev->nodes, CIL_NODE, node); + node->data = prev; + return SEPOL_EEXIST; + } + + return SEPOL_OK; +} + +int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor) +{ + int rc = SEPOL_ERR; + symtab_t *symtab = NULL; + + rc = cil_verify_name(db, (const char*)key, nflavor); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_get_symtab(ast_node->parent, &symtab, sflavor); + if (rc != SEPOL_OK) { + goto exit; + } + + ast_node->data = datum; + ast_node->flavor = nflavor; + + rc = cil_add_decl_to_symtab(db, symtab, key, datum, ast_node); + if (rc != SEPOL_OK) { + goto exit; + } + + if (ast_node->parent->flavor == CIL_MACRO) { + rc = cil_verify_decl_does_not_shadow_macro_parameter(ast_node->parent->data, ast_node, key); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static void cil_clear_node(struct cil_tree_node *ast_node) +{ + if (ast_node == NULL) { + return; + } + + ast_node->data = NULL; + ast_node->flavor = CIL_NONE; +} + +int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint16_t is_abstract) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_N_LISTS | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_block *block = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + if (db->qualified_names) { + cil_log(CIL_ERR, "Blocks are not allowed when the option for qualified names is used\n"); + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_block_init(&block); + + block->is_abstract = is_abstract; + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)block, (hashtab_key_t)key, CIL_SYM_BLOCKS, CIL_BLOCK); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad block declaration"); + cil_destroy_block(block); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_block(struct cil_block *block) +{ + struct cil_list_item *item; + struct cil_tree_node *bi_node; + struct cil_blockinherit *inherit; + + if (block == NULL) { + return; + } + + cil_symtab_datum_destroy(&block->datum); + cil_symtab_array_destroy(block->symtab); + if (block->bi_nodes != NULL) { + /* unlink blockinherit->block */ + cil_list_for_each(item, block->bi_nodes) { + bi_node = item->data; + /* the conditions should always be true, but better be sure */ + if (bi_node->flavor == CIL_BLOCKINHERIT) { + inherit = bi_node->data; + if (inherit->block == block) { + inherit->block = NULL; + } + } + } + cil_list_destroy(&block->bi_nodes, CIL_FALSE); + } + + free(block); +} + +int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_blockinherit *inherit = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + if (db->qualified_names) { + cil_log(CIL_ERR, "Block inherit rules are not allowed when the option for qualified names is used\n"); + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_blockinherit_init(&inherit); + + inherit->block_str = parse_current->next->data; + + ast_node->data = inherit; + ast_node->flavor = CIL_BLOCKINHERIT; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad blockinherit declaration"); + cil_destroy_blockinherit(inherit); + return rc; +} + +void cil_destroy_blockinherit(struct cil_blockinherit *inherit) +{ + if (inherit == NULL) { + return; + } + + if (inherit->block != NULL && inherit->block->bi_nodes != NULL) { + struct cil_tree_node *node; + struct cil_list_item *item; + + cil_list_for_each(item, inherit->block->bi_nodes) { + node = item->data; + if (node->data == inherit) { + cil_list_remove(inherit->block->bi_nodes, CIL_NODE, node, CIL_FALSE); + break; + } + } + } + + free(inherit); +} + +int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_blockabstract *abstract = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + if (db->qualified_names) { + cil_log(CIL_ERR, "Block abstract rules are not allowed when the option for qualified names is used\n"); + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_blockabstract_init(&abstract); + + abstract->block_str = parse_current->next->data; + + ast_node->data = abstract; + ast_node->flavor = CIL_BLOCKABSTRACT; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad blockabstract declaration"); + cil_destroy_blockabstract(abstract); + return rc; +} + +void cil_destroy_blockabstract(struct cil_blockabstract *abstract) +{ + if (abstract == NULL) { + return; + } + + free(abstract); +} + +int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_N_LISTS, + CIL_SYN_N_LISTS | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_in *in = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + if (db->qualified_names) { + cil_log(CIL_ERR, "In-statements are not allowed when the option for qualified names is used\n"); + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_in_init(&in); + + if (parse_current->next->next->data) { + char *is_after_str = parse_current->next->data; + if (is_after_str == CIL_KEY_IN_BEFORE) { + in->is_after = CIL_FALSE; + } else if (is_after_str == CIL_KEY_IN_AFTER) { + in->is_after = CIL_TRUE; + } else { + cil_log(CIL_ERR, "Value must be either \'before\' or \'after\'\n"); + rc = SEPOL_ERR; + goto exit; + } + in->block_str = parse_current->next->next->data; + } else { + in->is_after = CIL_FALSE; + in->block_str = parse_current->next->data; + } + + ast_node->data = in; + ast_node->flavor = CIL_IN; + + return SEPOL_OK; +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad in-statement"); + cil_destroy_in(in); + return rc; +} + +void cil_destroy_in(struct cil_in *in) +{ + if (in == NULL) { + return; + } + + cil_symtab_array_destroy(in->symtab); + + free(in); +} + +int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_class *class = NULL; + struct cil_tree_node *perms = NULL; + int rc = SEPOL_ERR; + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_class_init(&class); + + key = parse_current->next->data; + if (key == CIL_KEY_UNORDERED) { + cil_log(CIL_ERR, "'unordered' keyword is reserved and not a valid class name.\n"); + rc = SEPOL_ERR; + goto exit; + } + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)class, (hashtab_key_t)key, CIL_SYM_CLASSES, CIL_CLASS); + if (rc != SEPOL_OK) { + goto exit; + } + + if (parse_current->next->next != NULL) { + perms = parse_current->next->next->cl_head; + rc = cil_gen_perm_nodes(db, perms, ast_node, CIL_PERM, &class->num_perms); + if (rc != SEPOL_OK) { + goto exit; + } + if (class->num_perms > CIL_PERMS_PER_CLASS) { + cil_tree_log(parse_current, CIL_ERR, "Too many permissions in class '%s'", class->datum.name); + cil_tree_children_destroy(ast_node); + rc = SEPOL_ERR; + goto exit; + } + + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad class declaration"); + cil_destroy_class(class); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_class(struct cil_class *class) +{ + if (class == NULL) { + return; + } + + cil_symtab_datum_destroy(&class->datum); + cil_symtab_destroy(&class->perms); + + free(class); +} + +int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_classorder *classorder = NULL; + struct cil_list_item *curr = NULL; + struct cil_list_item *head = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_classorder_init(&classorder); + + rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASSORDER, &classorder->class_list_str); + if (rc != SEPOL_OK) { + goto exit; + } + + head = classorder->class_list_str->head; + cil_list_for_each(curr, classorder->class_list_str) { + if (curr->data == CIL_KEY_UNORDERED) { + if (curr == head && curr->next == NULL) { + cil_log(CIL_ERR, "Classorder 'unordered' keyword must be followed by one or more class.\n"); + rc = SEPOL_ERR; + goto exit; + } else if (curr != head) { + cil_log(CIL_ERR, "Classorder can only use 'unordered' keyword as the first item in the list.\n"); + rc = SEPOL_ERR; + goto exit; + } + } + } + + ast_node->data = classorder; + ast_node->flavor = CIL_CLASSORDER; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad classorder declaration"); + cil_destroy_classorder(classorder); + return rc; +} + +void cil_destroy_classorder(struct cil_classorder *classorder) +{ + if (classorder == NULL) { + return; + } + + if (classorder->class_list_str != NULL) { + cil_list_destroy(&classorder->class_list_str, 1); + } + + free(classorder); +} + +int cil_gen_perm(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms) +{ + char *key = NULL; + struct cil_perm *perm = NULL; + int rc = SEPOL_ERR; + + cil_perm_init(&perm); + + key = parse_current->data; + if (key == NULL) { + cil_log(CIL_ERR, "Bad permission\n"); + goto exit; + } + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)perm, (hashtab_key_t)key, CIL_SYM_PERMS, flavor); + if (rc != SEPOL_OK) { + goto exit; + } + + perm->value = *num_perms; + (*num_perms)++; + + return SEPOL_OK; + +exit: + cil_destroy_perm(perm); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_perm(struct cil_perm *perm) +{ + if (perm == NULL) { + return; + } + + cil_symtab_datum_destroy(&perm->datum); + cil_list_destroy(&perm->classperms, CIL_FALSE); + + free(perm); +} + +int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *new_ast = NULL; + + while(current_perm != NULL) { + if (current_perm->cl_head != NULL) { + + rc = SEPOL_ERR; + goto exit; + } + cil_tree_node_init(&new_ast); + new_ast->parent = ast_node; + new_ast->line = current_perm->line; + new_ast->hll_offset = current_perm->hll_offset; + + rc = cil_gen_perm(db, current_perm, new_ast, flavor, num_perms); + if (rc != SEPOL_OK) { + cil_tree_node_destroy(&new_ast); + goto exit; + } + + if (ast_node->cl_head == NULL) { + ast_node->cl_head = new_ast; + } else { + ast_node->cl_tail->next = new_ast; + } + ast_node->cl_tail = new_ast; + + current_perm = current_perm->next; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad permissions\n"); + cil_tree_children_destroy(ast_node); + cil_clear_node(ast_node); + return rc; +} + +int cil_fill_perms(struct cil_tree_node *start_perm, struct cil_list **perms) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_N_STRINGS | CIL_SYN_N_LISTS, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + rc = __cil_verify_syntax(start_perm->cl_head, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_gen_expr(start_perm, CIL_PERM, perms); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad permission list or expression\n"); + return rc; +} + +int cil_fill_classperms(struct cil_tree_node *parse_current, struct cil_classperms **cp) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_classperms_init(cp); + + (*cp)->class_str = parse_current->data; + + rc = cil_fill_perms(parse_current->next, &(*cp)->perm_strs); + if (rc != SEPOL_OK) { + cil_destroy_classperms(*cp); + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad class-permissions\n"); + *cp = NULL; + return rc; +} + +void cil_destroy_classperms(struct cil_classperms *cp) +{ + if (cp == NULL) { + return; + } + + cil_list_destroy(&cp->perm_strs, CIL_TRUE); + cil_list_destroy(&cp->perms, CIL_FALSE); + + free(cp); +} + +void cil_fill_classperms_set(struct cil_tree_node *parse_current, struct cil_classperms_set **cp_set) +{ + cil_classperms_set_init(cp_set); + (*cp_set)->set_str = parse_current->data; +} + +void cil_destroy_classperms_set(struct cil_classperms_set *cp_set) +{ + if (cp_set == NULL) { + return; + } + + free(cp_set); +} + +int cil_fill_classperms_list(struct cil_tree_node *parse_current, struct cil_list **cp_list) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *curr; + + if (parse_current == NULL || cp_list == NULL) { + goto exit; + } + + cil_list_init(cp_list, CIL_CLASSPERMS); + + curr = parse_current->cl_head; + + if (curr == NULL) { + /* Class-perms form: SET1 */ + struct cil_classperms_set *new_cp_set; + cil_fill_classperms_set(parse_current, &new_cp_set); + cil_list_append(*cp_list, CIL_CLASSPERMS_SET, new_cp_set); + } else if (curr->cl_head == NULL) { + /* Class-perms form: (CLASS1 (PERM1 ...)) */ + struct cil_classperms *new_cp; + rc = cil_fill_classperms(curr, &new_cp); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_append(*cp_list, CIL_CLASSPERMS, new_cp); + } else { + cil_log(CIL_ERR, "Bad class-permissions list syntax\n"); + rc = SEPOL_ERR; + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Problem filling class-permissions list\n"); + cil_list_destroy(cp_list, CIL_TRUE); + return rc; +} + +void cil_destroy_classperms_list(struct cil_list **cp_list) +{ + struct cil_list_item *curr; + + if (cp_list == NULL || *cp_list == NULL) { + return; + } + + cil_list_for_each(curr, *cp_list) { + if (curr->flavor == CIL_CLASSPERMS) { + cil_destroy_classperms(curr->data); + } else { + cil_destroy_classperms_set(curr->data); + } + } + + cil_list_destroy(cp_list, CIL_FALSE); +} + +int cil_gen_classpermission(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + char *key = NULL; + struct cil_classpermission *cp = NULL; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_classpermission_init(&cp); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)cp, (hashtab_key_t)key, CIL_SYM_CLASSPERMSETS, CIL_CLASSPERMISSION); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad classpermission declaration"); + cil_destroy_classpermission(cp); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_classpermission(struct cil_classpermission *cp) +{ + if (cp == NULL) { + return; + } + + if (cp->datum.name != NULL) { + cil_list_destroy(&cp->classperms, CIL_FALSE); + } else { + /* anonymous classpermission from call */ + cil_destroy_classperms_list(&cp->classperms); + } + + cil_symtab_datum_destroy(&cp->datum); + + + free(cp); +} + +int cil_gen_classpermissionset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + struct cil_classpermissionset *cps = NULL; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_classpermissionset_init(&cps); + + cps->set_str = parse_current->next->data; + + rc = cil_fill_classperms_list(parse_current->next->next, &cps->classperms); + if (rc != SEPOL_OK) { + goto exit; + } + + ast_node->data = cps; + ast_node->flavor = CIL_CLASSPERMISSIONSET; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad classpermissionset"); + cil_destroy_classpermissionset(cps); + return rc; +} + +void cil_destroy_classpermissionset(struct cil_classpermissionset *cps) +{ + if (cps == NULL) { + return; + } + + cil_destroy_classperms_list(&cps->classperms); + + free(cps); +} + +int cil_gen_map_class(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_class *map = NULL; + int rc = SEPOL_ERR; + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_class_init(&map); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)map, (hashtab_key_t)key, CIL_SYM_CLASSES, CIL_MAP_CLASS); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_gen_perm_nodes(db, parse_current->next->next->cl_head, ast_node, CIL_MAP_PERM, &map->num_perms); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad map class declaration"); + cil_destroy_class(map); + cil_clear_node(ast_node); + return rc; +} + +int cil_gen_classmapping(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + struct cil_classmapping *mapping = NULL; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_classmapping_init(&mapping); + + mapping->map_class_str = parse_current->next->data; + mapping->map_perm_str = parse_current->next->next->data; + + rc = cil_fill_classperms_list(parse_current->next->next->next, &mapping->classperms); + if (rc != SEPOL_OK) { + goto exit; + } + + ast_node->data = mapping; + ast_node->flavor = CIL_CLASSMAPPING; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad classmapping declaration"); + cil_destroy_classmapping(mapping); + return rc; +} + +void cil_destroy_classmapping(struct cil_classmapping *mapping) +{ + if (mapping == NULL) { + return; + } + + cil_destroy_classperms_list(&mapping->classperms); + + free(mapping); +} + +// TODO try to merge some of this with cil_gen_class (helper function for both) +int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_class *common = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_class_init(&common); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)common, (hashtab_key_t)key, CIL_SYM_COMMONS, CIL_COMMON); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_gen_perm_nodes(db, parse_current->next->next->cl_head, ast_node, CIL_PERM, &common->num_perms); + if (rc != SEPOL_OK) { + goto exit; + } + if (common->num_perms > CIL_PERMS_PER_CLASS) { + cil_tree_log(parse_current, CIL_ERR, "Too many permissions in common '%s'", common->datum.name); + cil_tree_children_destroy(ast_node); + rc = SEPOL_ERR; + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad common declaration"); + cil_destroy_class(common); + cil_clear_node(ast_node); + return rc; + +} + +int cil_gen_classcommon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_classcommon *clscom = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_classcommon_init(&clscom); + + clscom->class_str = parse_current->next->data; + clscom->common_str = parse_current->next->next->data; + + ast_node->data = clscom; + ast_node->flavor = CIL_CLASSCOMMON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad classcommon declaration"); + cil_destroy_classcommon(clscom); + return rc; + +} + +void cil_destroy_classcommon(struct cil_classcommon *clscom) +{ + if (clscom == NULL) { + return; + } + + free(clscom); +} + +int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_sid *sid = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_sid_init(&sid); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)sid, (hashtab_key_t)key, CIL_SYM_SIDS, CIL_SID); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad sid declaration"); + cil_destroy_sid(sid); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_sid(struct cil_sid *sid) +{ + if (sid == NULL) { + return; + } + + cil_symtab_datum_destroy(&sid->datum); + free(sid); +} + +int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_sidcontext *sidcon = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_sidcontext_init(&sidcon); + + sidcon->sid_str = parse_current->next->data; + + if (parse_current->next->next->cl_head == NULL) { + sidcon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&sidcon->context); + + rc = cil_fill_context(parse_current->next->next->cl_head, sidcon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = sidcon; + ast_node->flavor = CIL_SIDCONTEXT; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad sidcontext declaration"); + cil_destroy_sidcontext(sidcon); + return rc; +} + +void cil_destroy_sidcontext(struct cil_sidcontext *sidcon) +{ + if (sidcon == NULL) { + return; + } + + if (sidcon->context_str == NULL && sidcon->context != NULL) { + cil_destroy_context(sidcon->context); + } + + free(sidcon); +} + +int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_sidorder *sidorder = NULL; + struct cil_list_item *curr = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_sidorder_init(&sidorder); + + rc = cil_fill_list(parse_current->next->cl_head, CIL_SIDORDER, &sidorder->sid_list_str); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_list_for_each(curr, sidorder->sid_list_str) { + if (curr->data == CIL_KEY_UNORDERED) { + cil_log(CIL_ERR, "Sidorder cannot be unordered.\n"); + rc = SEPOL_ERR; + goto exit; + } + } + + ast_node->data = sidorder; + ast_node->flavor = CIL_SIDORDER; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad sidorder declaration"); + cil_destroy_sidorder(sidorder); + return rc; +} + +void cil_destroy_sidorder(struct cil_sidorder *sidorder) +{ + if (sidorder == NULL) { + return; + } + + if (sidorder->sid_list_str != NULL) { + cil_list_destroy(&sidorder->sid_list_str, 1); + } + + free(sidorder); +} + +int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_user *user = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_user_init(&user); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)user, (hashtab_key_t)key, CIL_SYM_USERS, CIL_USER); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad user declaration"); + cil_destroy_user(user); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_user(struct cil_user *user) +{ + if (user == NULL) { + return; + } + + cil_symtab_datum_destroy(&user->datum); + ksu_ebitmap_destroy(user->roles); + free(user->roles); + free(user); +} + +int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_userattribute *attr = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_userattribute_init(&attr); + + key = parse_current->next->data; + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_USERS, CIL_USERATTRIBUTE); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad userattribute declaration"); + cil_destroy_userattribute(attr); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_userattribute(struct cil_userattribute *attr) +{ + struct cil_list_item *expr = NULL; + struct cil_list_item *next = NULL; + + if (attr == NULL) { + return; + } + + if (attr->expr_list != NULL) { + /* we don't want to destroy the expression stacks (cil_list) inside + * this list cil_list_destroy destroys sublists, so we need to do it + * manually */ + expr = attr->expr_list->head; + while (expr != NULL) { + next = expr->next; + cil_list_item_destroy(&expr, CIL_FALSE); + expr = next; + } + free(attr->expr_list); + attr->expr_list = NULL; + } + + cil_symtab_datum_destroy(&attr->datum); + ksu_ebitmap_destroy(attr->users); + free(attr->users); + free(attr); +} + +int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_userattributeset *attrset = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_userattributeset_init(&attrset); + + attrset->attr_str = parse_current->next->data; + + rc = cil_gen_expr(parse_current->next->next, CIL_USER, &attrset->str_expr); + if (rc != SEPOL_OK) { + goto exit; + } + ast_node->data = attrset; + ast_node->flavor = CIL_USERATTRIBUTESET; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad userattributeset declaration"); + cil_destroy_userattributeset(attrset); + + return rc; +} + +void cil_destroy_userattributeset(struct cil_userattributeset *attrset) +{ + if (attrset == NULL) { + return; + } + + cil_list_destroy(&attrset->str_expr, CIL_TRUE); + cil_list_destroy(&attrset->datum_expr, CIL_FALSE); + + free(attrset); +} + +int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_userlevel *usrlvl = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_userlevel_init(&usrlvl); + + usrlvl->user_str = parse_current->next->data; + + if (parse_current->next->next->cl_head == NULL) { + usrlvl->level_str = parse_current->next->next->data; + } else { + cil_level_init(&usrlvl->level); + + rc = cil_fill_level(parse_current->next->next->cl_head, usrlvl->level); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = usrlvl; + ast_node->flavor = CIL_USERLEVEL; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad userlevel declaration"); + cil_destroy_userlevel(usrlvl); + return rc; +} + +void cil_destroy_userlevel(struct cil_userlevel *usrlvl) +{ + if (usrlvl == NULL) { + return; + } + + if (usrlvl->level_str == NULL && usrlvl->level != NULL) { + cil_destroy_level(usrlvl->level); + } + + free(usrlvl); +} + +int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_userrange *userrange = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_userrange_init(&userrange); + + userrange->user_str = parse_current->next->data; + + if (parse_current->next->next->cl_head == NULL) { + userrange->range_str = parse_current->next->next->data; + } else { + cil_levelrange_init(&userrange->range); + + rc = cil_fill_levelrange(parse_current->next->next->cl_head, userrange->range); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = userrange; + ast_node->flavor = CIL_USERRANGE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad userrange declaration"); + cil_destroy_userrange(userrange); + return rc; +} + +void cil_destroy_userrange(struct cil_userrange *userrange) +{ + if (userrange == NULL) { + return; + } + + if (userrange->range_str == NULL && userrange->range != NULL) { + cil_destroy_levelrange(userrange->range); + } + + free(userrange); +} + +int cil_gen_userprefix(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_userprefix *userprefix = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_userprefix_init(&userprefix); + + userprefix->user_str = parse_current->next->data; + userprefix->prefix_str = parse_current->next->next->data; + + ast_node->data = userprefix; + ast_node->flavor = CIL_USERPREFIX; + + return SEPOL_OK; +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad userprefix declaration"); + cil_destroy_userprefix(userprefix); + return rc; +} + +void cil_destroy_userprefix(struct cil_userprefix *userprefix) +{ + if (userprefix == NULL) { + return; + } + + free(userprefix); +} + +int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_selinuxuser *selinuxuser = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_selinuxuser_init(&selinuxuser); + + selinuxuser->name_str = parse_current->next->data; + selinuxuser->user_str = parse_current->next->next->data; + + if (parse_current->next->next->next->cl_head == NULL) { + selinuxuser->range_str = parse_current->next->next->next->data; + } else { + cil_levelrange_init(&selinuxuser->range); + + rc = cil_fill_levelrange(parse_current->next->next->next->cl_head, selinuxuser->range); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = selinuxuser; + ast_node->flavor = CIL_SELINUXUSER; + + return SEPOL_OK; +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuser declaration"); + cil_destroy_selinuxuser(selinuxuser); + return rc; +} + +int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_selinuxuser *selinuxuser = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_selinuxuser_init(&selinuxuser); + + selinuxuser->name_str = cil_strpool_add("__default__"); + selinuxuser->user_str = parse_current->next->data; + + if (parse_current->next->next->cl_head == NULL) { + selinuxuser->range_str = parse_current->next->next->data; + } else { + cil_levelrange_init(&selinuxuser->range); + + rc = cil_fill_levelrange(parse_current->next->next->cl_head, selinuxuser->range); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = selinuxuser; + ast_node->flavor = CIL_SELINUXUSERDEFAULT; + + return SEPOL_OK; +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuserdefault declaration"); + cil_destroy_selinuxuser(selinuxuser); + return rc; +} + +void cil_destroy_selinuxuser(struct cil_selinuxuser *selinuxuser) +{ + if (selinuxuser == NULL) { + return; + } + + if (selinuxuser->range_str == NULL && selinuxuser->range != NULL) { + cil_destroy_levelrange(selinuxuser->range); + } + + free(selinuxuser); +} + +int cil_gen_role(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_role *role = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_role_init(&role); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)role, (hashtab_key_t)key, CIL_SYM_ROLES, CIL_ROLE); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad role declaration"); + cil_destroy_role(role); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_role(struct cil_role *role) +{ + if (role == NULL) { + return; + } + + cil_symtab_datum_destroy(&role->datum); + ksu_ebitmap_destroy(role->types); + free(role->types); + free(role); +} + +int cil_gen_roletype(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_roletype *roletype = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_roletype_init(&roletype); + + roletype->role_str = parse_current->next->data; + roletype->type_str = parse_current->next->next->data; + + ast_node->data = roletype; + ast_node->flavor = CIL_ROLETYPE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad roletype declaration"); + cil_destroy_roletype(roletype); + return rc; +} + +void cil_destroy_roletype(struct cil_roletype *roletype) +{ + if (roletype == NULL) { + return; + } + + free(roletype); +} + +int cil_gen_userrole(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_userrole *userrole = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_userrole_init(&userrole); + + userrole->user_str = parse_current->next->data; + userrole->role_str = parse_current->next->next->data; + + ast_node->data = userrole; + ast_node->flavor = CIL_USERROLE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad userrole declaration"); + cil_destroy_userrole(userrole); + return rc; +} + +void cil_destroy_userrole(struct cil_userrole *userrole) +{ + if (userrole == NULL) { + return; + } + + free(userrole); +} + +int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_roletransition *roletrans = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_roletransition_init(&roletrans); + + roletrans->src_str = parse_current->next->data; + roletrans->tgt_str = parse_current->next->next->data; + roletrans->obj_str = parse_current->next->next->next->data; + roletrans->result_str = parse_current->next->next->next->next->data; + + ast_node->data = roletrans; + ast_node->flavor = CIL_ROLETRANSITION; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad roletransition rule"); + cil_destroy_roletransition(roletrans); + return rc; +} + +void cil_destroy_roletransition(struct cil_roletransition *roletrans) +{ + if (roletrans == NULL) { + return; + } + + free(roletrans); +} + +int cil_gen_roleallow(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_roleallow *roleallow = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_roleallow_init(&roleallow); + + roleallow->src_str = parse_current->next->data; + roleallow->tgt_str = parse_current->next->next->data; + + ast_node->data = roleallow; + ast_node->flavor = CIL_ROLEALLOW; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad roleallow rule"); + cil_destroy_roleallow(roleallow); + return rc; +} + +void cil_destroy_roleallow(struct cil_roleallow *roleallow) +{ + if (roleallow == NULL) { + return; + } + + free(roleallow); +} + +int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_roleattribute *attr = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_roleattribute_init(&attr); + + key = parse_current->next->data; + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_ROLES, CIL_ROLEATTRIBUTE); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad roleattribute declaration"); + cil_destroy_roleattribute(attr); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_roleattribute(struct cil_roleattribute *attr) +{ + if (attr == NULL) { + return; + } + + if (attr->expr_list != NULL) { + /* we don't want to destroy the expression stacks (cil_list) inside + * this list cil_list_destroy destroys sublists, so we need to do it + * manually */ + struct cil_list_item *expr = attr->expr_list->head; + while (expr != NULL) { + struct cil_list_item *next = expr->next; + cil_list_item_destroy(&expr, CIL_FALSE); + expr = next; + } + free(attr->expr_list); + attr->expr_list = NULL; + } + + cil_symtab_datum_destroy(&attr->datum); + ksu_ebitmap_destroy(attr->roles); + free(attr->roles); + free(attr); +} + +int cil_gen_roleattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_roleattributeset *attrset = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_roleattributeset_init(&attrset); + + attrset->attr_str = parse_current->next->data; + + rc = cil_gen_expr(parse_current->next->next, CIL_ROLE, &attrset->str_expr); + if (rc != SEPOL_OK) { + goto exit; + } + ast_node->data = attrset; + ast_node->flavor = CIL_ROLEATTRIBUTESET; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad roleattributeset declaration"); + cil_destroy_roleattributeset(attrset); + + return rc; +} + +void cil_destroy_roleattributeset(struct cil_roleattributeset *attrset) +{ + if (attrset == NULL) { + return; + } + + cil_list_destroy(&attrset->str_expr, CIL_TRUE); + cil_list_destroy(&attrset->datum_expr, CIL_FALSE); + + free(attrset); +} + +int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_avrule *rule = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_avrule_init(&rule); + + rule->is_extended = 0; + rule->rule_kind = rule_kind; + + rule->src_str = parse_current->next->data; + rule->tgt_str = parse_current->next->next->data; + + rc = cil_fill_classperms_list(parse_current->next->next->next, &rule->perms.classperms); + if (rc != SEPOL_OK) { + goto exit; + } + + ast_node->data = rule; + ast_node->flavor = CIL_AVRULE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad allow rule"); + cil_destroy_avrule(rule); + return rc; +} + +void cil_destroy_avrule(struct cil_avrule *rule) +{ + if (rule == NULL) { + return; + } + + if (!rule->is_extended) { + cil_destroy_classperms_list(&rule->perms.classperms); + } else { + if (rule->perms.x.permx_str == NULL && rule->perms.x.permx != NULL) { + cil_destroy_permissionx(rule->perms.x.permx); + } + } + + free(rule); +} + +static int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permissionx *permx) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + if (parse_current->data == CIL_KEY_IOCTL) { + permx->kind = CIL_PERMX_KIND_IOCTL; + } else { + cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\"\n", (char *)parse_current->data); + rc = SEPOL_ERR; + goto exit; + } + + permx->obj_str = parse_current->next->data; + + rc = cil_gen_expr(parse_current->next->next, CIL_PERMISSIONX, &permx->expr_str); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad permissionx content"); + return rc; +} + +int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_permissionx *permx = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_permissionx_init(&permx); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)permx, (hashtab_key_t)key, CIL_SYM_PERMX, CIL_PERMISSIONX); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_fill_permissionx(parse_current->next->next->cl_head, permx); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad permissionx statement"); + cil_destroy_permissionx(permx); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_permissionx(struct cil_permissionx *permx) +{ + if (permx == NULL) { + return; + } + + cil_symtab_datum_destroy(&permx->datum); + + cil_list_destroy(&permx->expr_str, CIL_TRUE); + ksu_ebitmap_destroy(permx->perms); + free(permx->perms); + free(permx); +} + +int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_avrule *rule = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_avrule_init(&rule); + + rule->is_extended = 1; + rule->rule_kind = rule_kind; + rule->src_str = parse_current->next->data; + rule->tgt_str = parse_current->next->next->data; + + if (parse_current->next->next->next->cl_head == NULL) { + rule->perms.x.permx_str = parse_current->next->next->next->data; + } else { + cil_permissionx_init(&rule->perms.x.permx); + + rc = cil_fill_permissionx(parse_current->next->next->next->cl_head, rule->perms.x.permx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = rule; + ast_node->flavor = CIL_AVRULEX; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad allowx rule"); + cil_destroy_avrule(rule); + return rc; +} + +int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_type_rule *rule = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_type_rule_init(&rule); + + rule->rule_kind = rule_kind; + rule->src_str = parse_current->next->data; + rule->tgt_str = parse_current->next->next->data; + rule->obj_str = parse_current->next->next->next->data; + rule->result_str = parse_current->next->next->next->next->data; + + ast_node->data = rule; + ast_node->flavor = CIL_TYPE_RULE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad type rule"); + cil_destroy_type_rule(rule); + return rc; +} + +void cil_destroy_type_rule(struct cil_type_rule *rule) +{ + if (rule == NULL) { + return; + } + + free(rule); +} + +int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_type *type = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_type_init(&type); + + key = parse_current->next->data; + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)type, (hashtab_key_t)key, CIL_SYM_TYPES, CIL_TYPE); + if (rc != SEPOL_OK) { + if (rc == SEPOL_EEXIST) { + cil_destroy_type(type); + type = NULL; + } else { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad type declaration"); + cil_destroy_type(type); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_type(struct cil_type *type) +{ + if (type == NULL) { + return; + } + + cil_symtab_datum_destroy(&type->datum); + free(type); +} + +int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_typeattribute *attr = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_typeattribute_init(&attr); + + key = parse_current->next->data; + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_TYPES, CIL_TYPEATTRIBUTE); + if (rc != SEPOL_OK) { + if (rc == SEPOL_EEXIST) { + cil_destroy_typeattribute(attr); + attr = NULL; + } else { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad typeattribute declaration"); + cil_destroy_typeattribute(attr); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_typeattribute(struct cil_typeattribute *attr) +{ + if (attr == NULL) { + return; + } + + cil_symtab_datum_destroy(&attr->datum); + + if (attr->expr_list != NULL) { + /* we don't want to destroy the expression stacks (cil_list) inside + * this list cil_list_destroy destroys sublists, so we need to do it + * manually */ + struct cil_list_item *expr = attr->expr_list->head; + while (expr != NULL) { + struct cil_list_item *next = expr->next; + cil_list_item_destroy(&expr, CIL_FALSE); + expr = next; + } + free(attr->expr_list); + attr->expr_list = NULL; + } + ksu_ebitmap_destroy(attr->types); + free(attr->types); + free(attr); +} + +int cil_gen_bool(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, int tunableif) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_bool *boolean = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_bool_init(&boolean); + + key = parse_current->next->data; + + if (parse_current->next->next->data == CIL_KEY_CONDTRUE) { + boolean->value = CIL_TRUE; + } else if (parse_current->next->next->data == CIL_KEY_CONDFALSE) { + boolean->value = CIL_FALSE; + } else { + cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); + rc = SEPOL_ERR; + goto exit; + } + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)boolean, (hashtab_key_t)key, CIL_SYM_BOOLS, CIL_BOOL); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + if (tunableif) { + cil_tree_log(parse_current, CIL_ERR, "Bad tunable (treated as a boolean due to preserve-tunables) declaration"); + } else { + cil_tree_log(parse_current, CIL_ERR, "Bad boolean declaration"); + } + cil_destroy_bool(boolean); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_bool(struct cil_bool *boolean) +{ + if (boolean == NULL) { + return; + } + + cil_symtab_datum_destroy(&boolean->datum); + free(boolean); +} + +int cil_gen_tunable(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_tunable *tunable = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_tunable_init(&tunable); + + key = parse_current->next->data; + + if (parse_current->next->next->data == CIL_KEY_CONDTRUE) { + tunable->value = CIL_TRUE; + } else if (parse_current->next->next->data == CIL_KEY_CONDFALSE) { + tunable->value = CIL_FALSE; + } else { + cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); + rc = SEPOL_ERR; + goto exit; + } + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)tunable, (hashtab_key_t)key, CIL_SYM_TUNABLES, CIL_TUNABLE); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad tunable declaration"); + cil_destroy_tunable(tunable); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_tunable(struct cil_tunable *tunable) +{ + if (tunable == NULL) { + return; + } + + cil_symtab_datum_destroy(&tunable->datum); + free(tunable); +} + +static enum cil_flavor __cil_get_expr_operator_flavor(const char *op) +{ + if (op == NULL) return CIL_NONE; + else if (op == CIL_KEY_AND) return CIL_AND; + else if (op == CIL_KEY_OR) return CIL_OR; + else if (op == CIL_KEY_NOT) return CIL_NOT; + else if (op == CIL_KEY_EQ) return CIL_EQ; /* Only conditional */ + else if (op == CIL_KEY_NEQ) return CIL_NEQ; /* Only conditional */ + else if (op == CIL_KEY_XOR) return CIL_XOR; + else if (op == CIL_KEY_ALL) return CIL_ALL; /* Only set and permissionx */ + else if (op == CIL_KEY_RANGE) return CIL_RANGE; /* Only catset and permissionx */ + else return CIL_NONE; +} + +static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr); + +static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr) +{ + int rc = SEPOL_ERR; + enum cil_flavor op; + + op = __cil_get_expr_operator_flavor(current->data); + + rc = cil_verify_expr_syntax(current, op, flavor); + if (rc != SEPOL_OK) { + goto exit; + } + + if (op != CIL_NONE) { + cil_list_append(expr, CIL_OP, (void *)op); + current = current->next; + } + + for (;current != NULL; current = current->next) { + rc = __cil_fill_expr(current, flavor, expr); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr) +{ + int rc = SEPOL_ERR; + + if (current->cl_head == NULL) { + enum cil_flavor op = __cil_get_expr_operator_flavor(current->data); + if (op != CIL_NONE) { + cil_log(CIL_ERR, "Operator (%s) not in an expression\n", (char*)current->data); + goto exit; + } + cil_list_append(expr, CIL_STRING, current->data); + } else { + struct cil_list *sub_expr; + cil_list_init(&sub_expr, flavor); + rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr); + if (rc != SEPOL_OK) { + cil_list_destroy(&sub_expr, CIL_TRUE); + goto exit; + } + cil_list_append(expr, CIL_LIST, sub_expr); + } + + return SEPOL_OK; + +exit: + return rc; +} + + +int cil_gen_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) +{ + int rc = SEPOL_ERR; + + cil_list_init(expr, flavor); + + if (current->cl_head == NULL) { + rc = __cil_fill_expr(current, flavor, *expr); + } else { + rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr); + } + + if (rc != SEPOL_OK) { + cil_list_destroy(expr, CIL_TRUE); + cil_log(CIL_ERR, "Bad expression\n"); + } + + return rc; +} + +static enum cil_flavor __cil_get_constraint_operator_flavor(const char *op) +{ + if (op == CIL_KEY_AND) return CIL_AND; + else if (op == CIL_KEY_OR) return CIL_OR; + else if (op == CIL_KEY_NOT) return CIL_NOT; + else if (op == CIL_KEY_EQ) return CIL_EQ; + else if (op == CIL_KEY_NEQ) return CIL_NEQ; + else if (op == CIL_KEY_CONS_DOM) return CIL_CONS_DOM; + else if (op == CIL_KEY_CONS_DOMBY) return CIL_CONS_DOMBY; + else if (op == CIL_KEY_CONS_INCOMP) return CIL_CONS_INCOMP; + else return CIL_NONE; +} + +static enum cil_flavor __cil_get_constraint_operand_flavor(const char *operand) +{ + if (operand == NULL) return CIL_LIST; + else if (operand == CIL_KEY_CONS_T1) return CIL_CONS_T1; + else if (operand == CIL_KEY_CONS_T2) return CIL_CONS_T2; + else if (operand == CIL_KEY_CONS_T3) return CIL_CONS_T3; + else if (operand == CIL_KEY_CONS_R1) return CIL_CONS_R1; + else if (operand == CIL_KEY_CONS_R2) return CIL_CONS_R2; + else if (operand == CIL_KEY_CONS_R3) return CIL_CONS_R3; + else if (operand == CIL_KEY_CONS_U1) return CIL_CONS_U1; + else if (operand == CIL_KEY_CONS_U2) return CIL_CONS_U2; + else if (operand == CIL_KEY_CONS_U3) return CIL_CONS_U3; + else if (operand == CIL_KEY_CONS_L1) return CIL_CONS_L1; + else if (operand == CIL_KEY_CONS_L2) return CIL_CONS_L2; + else if (operand == CIL_KEY_CONS_H1) return CIL_CONS_H1; + else if (operand == CIL_KEY_CONS_H2) return CIL_CONS_H2; + else return CIL_STRING; +} + +static int __cil_fill_constraint_leaf_expr(struct cil_tree_node *current, enum cil_flavor expr_flavor, enum cil_flavor op, struct cil_list **leaf_expr) +{ + int rc = SEPOL_ERR; + enum cil_flavor leaf_expr_flavor = CIL_NONE; + enum cil_flavor l_flavor = CIL_NONE; + enum cil_flavor r_flavor = CIL_NONE; + + l_flavor = __cil_get_constraint_operand_flavor(current->next->data); + r_flavor = __cil_get_constraint_operand_flavor(current->next->next->data); + + switch (l_flavor) { + case CIL_CONS_U1: + case CIL_CONS_U2: + case CIL_CONS_U3: + leaf_expr_flavor = CIL_USER; + break; + case CIL_CONS_R1: + case CIL_CONS_R2: + case CIL_CONS_R3: + leaf_expr_flavor = CIL_ROLE; + break; + case CIL_CONS_T1: + case CIL_CONS_T2: + case CIL_CONS_T3: + leaf_expr_flavor = CIL_TYPE; + break; + case CIL_CONS_L1: + case CIL_CONS_L2: + case CIL_CONS_H1: + case CIL_CONS_H2: + leaf_expr_flavor = CIL_LEVEL; + break; + default: + cil_log(CIL_ERR, "Invalid left operand (%s)\n", (char*)current->next->data); + goto exit; + } + + rc = cil_verify_constraint_leaf_expr_syntax(l_flavor, r_flavor, op, expr_flavor); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_list_init(leaf_expr, leaf_expr_flavor); + + cil_list_append(*leaf_expr, CIL_OP, (void *)op); + + cil_list_append(*leaf_expr, CIL_CONS_OPERAND, (void *)l_flavor); + + if (r_flavor == CIL_STRING) { + cil_list_append(*leaf_expr, CIL_STRING, current->next->next->data); + } else if (r_flavor == CIL_LIST) { + struct cil_list *sub_list; + rc = cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list); + if (rc != SEPOL_OK) { + cil_list_destroy(leaf_expr, CIL_TRUE); + goto exit; + } + cil_list_append(*leaf_expr, CIL_LIST, sub_list); + } else { + cil_list_append(*leaf_expr, CIL_CONS_OPERAND, (void *)r_flavor); + } + + return SEPOL_OK; + +exit: + + return SEPOL_ERR; +} + +static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) +{ + int rc = SEPOL_ERR; + enum cil_flavor op; + struct cil_list *lexpr; + struct cil_list *rexpr; + + if (current->data == NULL || current->cl_head != NULL) { + cil_log(CIL_ERR, "Expected a string at the start of the constraint expression\n"); + goto exit; + } + + op = __cil_get_constraint_operator_flavor(current->data); + + rc = cil_verify_constraint_expr_syntax(current, op); + if (rc != SEPOL_OK) { + goto exit; + } + + switch (op) { + case CIL_EQ: + case CIL_NEQ: + case CIL_CONS_DOM: + case CIL_CONS_DOMBY: + case CIL_CONS_INCOMP: + rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr); + if (rc != SEPOL_OK) { + goto exit; + } + break; + case CIL_NOT: + rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_init(expr, flavor); + cil_list_append(*expr, CIL_OP, (void *)op); + cil_list_append(*expr, CIL_LIST, lexpr); + break; + default: + rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr); + if (rc != SEPOL_OK) { + goto exit; + } + rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr); + if (rc != SEPOL_OK) { + cil_list_destroy(&lexpr, CIL_TRUE); + goto exit; + } + cil_list_init(expr, flavor); + cil_list_append(*expr, CIL_OP, (void *)op); + cil_list_append(*expr, CIL_LIST, lexpr); + cil_list_append(*expr, CIL_LIST, rexpr); + break; + } + + return SEPOL_OK; +exit: + + return rc; +} + +static int cil_gen_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) +{ + int rc = SEPOL_ERR; + + if (current->cl_head == NULL) { + goto exit; + } + + rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + + cil_log(CIL_ERR, "Bad expression tree for constraint\n"); + return rc; +} + +int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, int tunableif) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_LIST, + CIL_SYN_LIST | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_booleanif *bif = NULL; + struct cil_tree_node *next = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_boolif_init(&bif); + bif->preserved_tunable = tunableif; + + rc = cil_gen_expr(parse_current->next, CIL_BOOL, &bif->str_expr); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_verify_conditional_blocks(parse_current->next->next); + if (rc != SEPOL_OK) { + goto exit; + } + + /* Destroying expr tree */ + next = parse_current->next->next; + cil_tree_subtree_destroy(parse_current->next); + parse_current->next = next; + + ast_node->flavor = CIL_BOOLEANIF; + ast_node->data = bif; + + return SEPOL_OK; + +exit: + if (tunableif) { + cil_tree_log(parse_current, CIL_ERR, "Bad tunableif (treated as a booleanif due to preserve-tunables) declaration"); + } else { + cil_tree_log(parse_current, CIL_ERR, "Bad booleanif declaration"); + } + cil_destroy_boolif(bif); + return rc; +} + +void cil_destroy_boolif(struct cil_booleanif *bif) +{ + if (bif == NULL) { + return; + } + + cil_list_destroy(&bif->str_expr, CIL_TRUE); + cil_list_destroy(&bif->datum_expr, CIL_FALSE); + + free(bif); +} + +int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_LIST, + CIL_SYN_LIST | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_tunableif *tif = NULL; + struct cil_tree_node *next = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_tunif_init(&tif); + + rc = cil_gen_expr(parse_current->next, CIL_TUNABLE, &tif->str_expr); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_verify_conditional_blocks(parse_current->next->next); + if (rc != SEPOL_OK) { + goto exit; + } + + /* Destroying expr tree */ + next = parse_current->next->next; + cil_tree_subtree_destroy(parse_current->next); + parse_current->next = next; + + ast_node->flavor = CIL_TUNABLEIF; + ast_node->data = tif; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad tunableif declaration"); + cil_destroy_tunif(tif); + return rc; +} + +void cil_destroy_tunif(struct cil_tunableif *tif) +{ + if (tif == NULL) { + return; + } + + cil_list_destroy(&tif->str_expr, CIL_TRUE); + cil_list_destroy(&tif->datum_expr, CIL_FALSE); + + free(tif); +} + +int cil_gen_condblock(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_N_LISTS, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_condblock *cb = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + if (ast_node->parent->flavor != CIL_BOOLEANIF && ast_node->parent->flavor != CIL_TUNABLEIF) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Conditional statements must be a direct child of a tunableif or booleanif statement.\n"); + goto exit; + } + + ast_node->flavor = CIL_CONDBLOCK; + + cil_condblock_init(&cb); + cb->flavor = flavor; + + ast_node->data = cb; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad %s condition declaration", + (char*)parse_current->data); + cil_destroy_condblock(cb); + return rc; +} + +void cil_destroy_condblock(struct cil_condblock *cb) +{ + if (cb == NULL) { + return; + } + + cil_symtab_array_destroy(cb->symtab); + free(cb); +} + +int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_alias *alias = NULL; + enum cil_sym_index sym_index; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_alias_init(&alias); + + key = parse_current->next->data; + + rc = cil_flavor_to_symtab_index(flavor, &sym_index); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)alias, (hashtab_key_t)key, sym_index, flavor); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", (char*)parse_current->data); + cil_destroy_alias(alias); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_alias(struct cil_alias *alias) +{ + if (alias == NULL) { + return; + } + + cil_symtab_datum_destroy(&alias->datum); + alias->actual = NULL; + + free(alias); +} + +int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_aliasactual *aliasactual = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + if ((flavor == CIL_TYPEALIAS && parse_current->next->data == CIL_KEY_SELF) || parse_current->next->next->data == CIL_KEY_SELF) { + cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); + rc = SEPOL_ERR; + goto exit; + } + + cil_aliasactual_init(&aliasactual); + + aliasactual->alias_str = parse_current->next->data; + + aliasactual->actual_str = parse_current->next->next->data; + + ast_node->data = aliasactual; + ast_node->flavor = flavor; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad %s association", cil_node_to_string(parse_current)); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_aliasactual(struct cil_aliasactual *aliasactual) +{ + if (aliasactual == NULL) { + return; + } + + free(aliasactual); +} + +int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_typeattributeset *attrset = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_typeattributeset_init(&attrset); + + attrset->attr_str = parse_current->next->data; + + rc = cil_gen_expr(parse_current->next->next, CIL_TYPE, &attrset->str_expr); + if (rc != SEPOL_OK) { + goto exit; + } + ast_node->data = attrset; + ast_node->flavor = CIL_TYPEATTRIBUTESET; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad typeattributeset statement"); + cil_destroy_typeattributeset(attrset); + return rc; +} + +void cil_destroy_typeattributeset(struct cil_typeattributeset *attrset) +{ + if (attrset == NULL) { + return; + } + + cil_list_destroy(&attrset->str_expr, CIL_TRUE); + cil_list_destroy(&attrset->datum_expr, CIL_FALSE); + + free(attrset); +} + +int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING, + CIL_SYN_END + }; + char *expand_str; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_expandtypeattribute *expandattr = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_expandtypeattribute_init(&expandattr); + + if (parse_current->next->cl_head == NULL) { + cil_list_init(&expandattr->attr_strs, CIL_TYPE); + cil_list_append(expandattr->attr_strs, CIL_STRING, parse_current->next->data); + } else { + rc = cil_fill_list(parse_current->next->cl_head, CIL_TYPE, &expandattr->attr_strs); + if (rc != SEPOL_OK) { + goto exit; + } + } + + expand_str = parse_current->next->next->data; + + if (expand_str == CIL_KEY_CONDTRUE) { + expandattr->expand = CIL_TRUE; + } else if (expand_str == CIL_KEY_CONDFALSE) { + expandattr->expand = CIL_FALSE; + } else { + cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); + rc = SEPOL_ERR; + goto exit; + } + + ast_node->data = expandattr; + ast_node->flavor = CIL_EXPANDTYPEATTRIBUTE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad expandtypeattribute statement"); + cil_destroy_expandtypeattribute(expandattr); + return rc; +} + +void cil_destroy_expandtypeattribute(struct cil_expandtypeattribute *expandattr) +{ + if (expandattr == NULL) { + return; + } + + cil_list_destroy(&expandattr->attr_strs, CIL_TRUE); + + cil_list_destroy(&expandattr->attr_datums, CIL_FALSE); + + free(expandattr); +} + +int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_typepermissive *typeperm = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_typepermissive_init(&typeperm); + + typeperm->type_str = parse_current->next->data; + + ast_node->data = typeperm; + ast_node->flavor = CIL_TYPEPERMISSIVE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad typepermissive declaration"); + cil_destroy_typepermissive(typeperm); + return rc; +} + +void cil_destroy_typepermissive(struct cil_typepermissive *typeperm) +{ + if (typeperm == NULL) { + return; + } + + free(typeperm); +} + +int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *s1, *s2, *s3, *s4, *s5; + + if (db == NULL || parse_current == NULL || ast_node == NULL ) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + s1 = parse_current->next->data; + s2 = parse_current->next->next->data; + s3 = parse_current->next->next->next->data; + s4 = parse_current->next->next->next->next->data; + s5 = NULL; + + if (parse_current->next->next->next->next->next) { + if (s4 == CIL_KEY_STAR) { + s4 = parse_current->next->next->next->next->next->data; + } else { + s5 = parse_current->next->next->next->next->next->data; + } + } + + if (s5) { + struct cil_nametypetransition *nametypetrans = NULL; + + cil_nametypetransition_init(&nametypetrans); + + nametypetrans->src_str = s1; + nametypetrans->tgt_str = s2; + nametypetrans->obj_str = s3; + nametypetrans->result_str = s5; + nametypetrans->name_str = s4; + + ast_node->data = nametypetrans; + ast_node->flavor = CIL_NAMETYPETRANSITION; + } else { + struct cil_type_rule *rule = NULL; + + cil_type_rule_init(&rule); + + rule->rule_kind = CIL_TYPE_TRANSITION; + rule->src_str = s1; + rule->tgt_str = s2; + rule->obj_str = s3; + rule->result_str = s4; + + ast_node->data = rule; + ast_node->flavor = CIL_TYPE_RULE; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad typetransition declaration"); + return rc; +} + +void cil_destroy_name(struct cil_name *name) +{ + if (name == NULL) { + return; + } + + cil_symtab_datum_destroy(&name->datum); + free(name); +} + +void cil_destroy_typetransition(struct cil_nametypetransition *nametypetrans) +{ + if (nametypetrans == NULL) { + return; + } + + free(nametypetrans); +} + +int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_rangetransition *rangetrans = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL ) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_rangetransition_init(&rangetrans); + + rangetrans->src_str = parse_current->next->data; + rangetrans->exec_str = parse_current->next->next->data; + rangetrans->obj_str = parse_current->next->next->next->data; + + rangetrans->range_str = NULL; + + if (parse_current->next->next->next->next->cl_head == NULL) { + rangetrans->range_str = parse_current->next->next->next->next->data; + } else { + cil_levelrange_init(&rangetrans->range); + + rc = cil_fill_levelrange(parse_current->next->next->next->next->cl_head, rangetrans->range); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = rangetrans; + ast_node->flavor = CIL_RANGETRANSITION; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad rangetransition declaration"); + cil_destroy_rangetransition(rangetrans); + return rc; +} + +void cil_destroy_rangetransition(struct cil_rangetransition *rangetrans) +{ + if (rangetrans == NULL) { + return; + } + + if (rangetrans->range_str == NULL && rangetrans->range != NULL) { + cil_destroy_levelrange(rangetrans->range); + } + + free(rangetrans); +} + +int cil_gen_sensitivity(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_sens *sens = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_sens_init(&sens); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)sens, (hashtab_key_t)key, CIL_SYM_SENS, CIL_SENS); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad sensitivity declaration"); + cil_destroy_sensitivity(sens); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_sensitivity(struct cil_sens *sens) +{ + if (sens == NULL) { + return; + } + + cil_symtab_datum_destroy(&sens->datum); + + cil_list_destroy(&sens->cats_list, CIL_FALSE); + + free(sens); +} + +int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_cat *cat = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_cat_init(&cat); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)cat, (hashtab_key_t)key, CIL_SYM_CATS, CIL_CAT); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad category declaration"); + cil_destroy_category(cat); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_category(struct cil_cat *cat) +{ + if (cat == NULL) { + return; + } + + cil_symtab_datum_destroy(&cat->datum); + free(cat); +} + +static int cil_gen_catset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_catset *catset = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_catset_init(&catset); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)catset, (hashtab_key_t)key, CIL_SYM_CATS, CIL_CATSET); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_fill_cats(parse_current->next->next, &catset->cats); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad categoryset declaration"); + cil_destroy_catset(catset); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_catset(struct cil_catset *catset) +{ + if (catset == NULL) { + return; + } + + cil_symtab_datum_destroy(&catset->datum); + + cil_destroy_cats(catset->cats); + + free(catset); +} + +int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_catorder *catorder = NULL; + struct cil_list_item *curr = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_catorder_init(&catorder); + + rc = cil_fill_list(parse_current->next->cl_head, CIL_CATORDER, &catorder->cat_list_str); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_list_for_each(curr, catorder->cat_list_str) { + if (curr->data == CIL_KEY_UNORDERED) { + cil_log(CIL_ERR, "Category order cannot be unordered.\n"); + rc = SEPOL_ERR; + goto exit; + } + } + + ast_node->data = catorder; + ast_node->flavor = CIL_CATORDER; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad categoryorder declaration"); + cil_destroy_catorder(catorder); + return rc; +} + +void cil_destroy_catorder(struct cil_catorder *catorder) +{ + if (catorder == NULL) { + return; + } + + if (catorder->cat_list_str != NULL) { + cil_list_destroy(&catorder->cat_list_str, 1); + } + + free(catorder); +} + +int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_sensorder *sensorder = NULL; + struct cil_list_item *curr = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_sensorder_init(&sensorder); + + rc = cil_fill_list(parse_current->next->cl_head, CIL_SENSITIVITYORDER, &sensorder->sens_list_str); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_list_for_each(curr, sensorder->sens_list_str) { + if (curr->data == CIL_KEY_UNORDERED) { + cil_log(CIL_ERR, "Sensitivity order cannot be unordered.\n"); + rc = SEPOL_ERR; + goto exit; + } + } + + ast_node->data = sensorder; + ast_node->flavor = CIL_SENSITIVITYORDER; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad sensitivityorder declaration"); + cil_destroy_sensitivityorder(sensorder); + return rc; +} + +void cil_destroy_sensitivityorder(struct cil_sensorder *sensorder) +{ + if (sensorder == NULL) { + return; + } + + if (sensorder->sens_list_str != NULL) { + cil_list_destroy(&sensorder->sens_list_str, CIL_TRUE); + } + + free(sensorder); +} + +int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_senscat *senscat = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_senscat_init(&senscat); + + senscat->sens_str = parse_current->next->data; + + rc = cil_fill_cats(parse_current->next->next, &senscat->cats); + if (rc != SEPOL_OK) { + goto exit; + } + + ast_node->data = senscat; + ast_node->flavor = CIL_SENSCAT; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad sensitivitycategory declaration"); + cil_destroy_senscat(senscat); + return rc; +} + +void cil_destroy_senscat(struct cil_senscat *senscat) +{ + if (senscat == NULL) { + return; + } + + cil_destroy_cats(senscat->cats); + + free(senscat); +} + +int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_level *level = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_level_init(&level); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)level, (hashtab_key_t)key, CIL_SYM_LEVELS, CIL_LEVEL); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_fill_level(parse_current->next->next->cl_head, level); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad level declaration"); + cil_destroy_level(level); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_level(struct cil_level *level) +{ + if (level == NULL) { + return; + } + + cil_symtab_datum_destroy(&level->datum); + + cil_destroy_cats(level->cats); + + free(level); +} + +/* low should be pointing to either the name of the low level or to an open paren for an anonymous low level */ +int cil_fill_levelrange(struct cil_tree_node *low, struct cil_levelrange *lvlrange) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + + if (low == NULL || lvlrange == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(low, syntax, syntax_len); + if (rc != SEPOL_OK) { + + goto exit; + } + + if (low->cl_head == NULL) { + lvlrange->low_str = low->data; + } else { + cil_level_init(&lvlrange->low); + rc = cil_fill_level(low->cl_head, lvlrange->low); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (low->next->cl_head == NULL) { + lvlrange->high_str = low->next->data; + } else { + cil_level_init(&lvlrange->high); + rc = cil_fill_level(low->next->cl_head, lvlrange->high); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad levelrange\n"); + return rc; +} + +int cil_gen_levelrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_levelrange *lvlrange = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_levelrange_init(&lvlrange); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)lvlrange, (hashtab_key_t)key, CIL_SYM_LEVELRANGES, CIL_LEVELRANGE); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_fill_levelrange(parse_current->next->next->cl_head, lvlrange); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad levelrange declaration"); + cil_destroy_levelrange(lvlrange); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_levelrange(struct cil_levelrange *lvlrange) +{ + if (lvlrange == NULL) { + return; + } + + cil_symtab_datum_destroy(&lvlrange->datum); + + if (lvlrange->low_str == NULL) { + cil_destroy_level(lvlrange->low); + } + + if (lvlrange->high_str == NULL) { + cil_destroy_level(lvlrange->high); + } + + free(lvlrange); +} + +int cil_gen_constrain(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_constrain *cons = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_constrain_init(&cons); + + rc = cil_fill_classperms_list(parse_current->next, &cons->classperms); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_gen_constraint_expr(parse_current->next->next, flavor, &cons->str_expr); + if (rc != SEPOL_OK) { + goto exit; + } + + ast_node->data = cons; + ast_node->flavor = flavor; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad constrain declaration"); + cil_destroy_constrain(cons); + return rc; +} + +void cil_destroy_constrain(struct cil_constrain *cons) +{ + if (cons == NULL) { + return; + } + + cil_destroy_classperms_list(&cons->classperms); + cil_list_destroy(&cons->str_expr, CIL_TRUE); + cil_list_destroy(&cons->datum_expr, CIL_FALSE); + + free(cons); +} + +int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_validatetrans *validtrans = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_validatetrans_init(&validtrans); + + validtrans->class_str = parse_current->next->data; + + rc = cil_gen_constraint_expr(parse_current->next->next, flavor, &validtrans->str_expr); + if (rc != SEPOL_OK) { + goto exit; + } + + ast_node->data = validtrans; + ast_node->flavor = flavor; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad validatetrans declaration"); + cil_destroy_validatetrans(validtrans); + return rc; + + +} + +void cil_destroy_validatetrans(struct cil_validatetrans *validtrans) +{ + if (validtrans == NULL) { + return; + } + + cil_list_destroy(&validtrans->str_expr, CIL_TRUE); + cil_list_destroy(&validtrans->datum_expr, CIL_FALSE); + + free(validtrans); +} + +/* Fills in context starting from user */ +int cil_fill_context(struct cil_tree_node *user_node, struct cil_context *context) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + + if (user_node == NULL || context == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(user_node, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + context->user_str = user_node->data; + context->role_str = user_node->next->data; + context->type_str = user_node->next->next->data; + + context->range_str = NULL; + + if (user_node->next->next->next->cl_head == NULL) { + context->range_str = user_node->next->next->next->data; + } else { + cil_levelrange_init(&context->range); + + rc = cil_fill_levelrange(user_node->next->next->next->cl_head, context->range); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad context\n"); + return rc; +} + +int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_context *context = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_context_init(&context); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)context, (hashtab_key_t)key, CIL_SYM_CONTEXTS, CIL_CONTEXT); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_fill_context(parse_current->next->next->cl_head, context); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad context declaration"); + cil_destroy_context(context); + cil_clear_node(ast_node); + return SEPOL_ERR; +} + +void cil_destroy_context(struct cil_context *context) +{ + if (context == NULL) { + return; + } + + cil_symtab_datum_destroy(&context->datum); + + if (context->range_str == NULL && context->range != NULL) { + cil_destroy_levelrange(context->range); + } + + free(context); +} + +int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_filecon *filecon = NULL; + char *type = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + type = parse_current->next->next->data; + cil_filecon_init(&filecon); + + filecon->path_str = parse_current->next->data; + + if (type == CIL_KEY_ANY) { + filecon->type = CIL_FILECON_ANY; + } else if (type == CIL_KEY_FILE) { + filecon->type = CIL_FILECON_FILE; + } else if (type == CIL_KEY_DIR) { + filecon->type = CIL_FILECON_DIR; + } else if (type == CIL_KEY_CHAR) { + filecon->type = CIL_FILECON_CHAR; + } else if (type == CIL_KEY_BLOCK) { + filecon->type = CIL_FILECON_BLOCK; + } else if (type == CIL_KEY_SOCKET) { + filecon->type = CIL_FILECON_SOCKET; + } else if (type == CIL_KEY_PIPE) { + filecon->type = CIL_FILECON_PIPE; + } else if (type == CIL_KEY_SYMLINK) { + filecon->type = CIL_FILECON_SYMLINK; + } else { + cil_log(CIL_ERR, "Invalid file type\n"); + rc = SEPOL_ERR; + goto exit; + } + + if (parse_current->next->next->next->cl_head == NULL) { + filecon->context_str = parse_current->next->next->next->data; + } else { + if (parse_current->next->next->next->cl_head->next == NULL) { + filecon->context = NULL; + } else { + cil_context_init(&filecon->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, filecon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + ast_node->data = filecon; + ast_node->flavor = CIL_FILECON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad filecon declaration"); + cil_destroy_filecon(filecon); + return rc; +} + +//TODO: Should we be checking if the pointer is NULL when passed in? +void cil_destroy_filecon(struct cil_filecon *filecon) +{ + if (filecon == NULL) { + return; + } + + if (filecon->context_str == NULL && filecon->context != NULL) { + cil_destroy_context(filecon->context); + } + + free(filecon); +} + +int cil_gen_ibpkeycon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax) / sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_ibpkeycon *ibpkeycon = NULL; + + if (!parse_current || !ast_node) + goto exit; + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) + goto exit; + + cil_ibpkeycon_init(&ibpkeycon); + + ibpkeycon->subnet_prefix_str = parse_current->next->data; + + if (parse_current->next->next->cl_head) { + if (parse_current->next->next->cl_head->next && + !parse_current->next->next->cl_head->next->next) { + rc = cil_fill_integer(parse_current->next->next->cl_head, &ibpkeycon->pkey_low, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibpkey specified\n"); + goto exit; + } + rc = cil_fill_integer(parse_current->next->next->cl_head->next, &ibpkeycon->pkey_high, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibpkey specified\n"); + goto exit; + } + } else { + cil_log(CIL_ERR, "Improper ibpkey range specified\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_fill_integer(parse_current->next->next, &ibpkeycon->pkey_low, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibpkey specified\n"); + goto exit; + } + ibpkeycon->pkey_high = ibpkeycon->pkey_low; + } + + if (!parse_current->next->next->next->cl_head) { + ibpkeycon->context_str = parse_current->next->next->next->data; + } else { + cil_context_init(&ibpkeycon->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, ibpkeycon->context); + if (rc != SEPOL_OK) + goto exit; + } + + ast_node->data = ibpkeycon; + ast_node->flavor = CIL_IBPKEYCON; + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad ibpkeycon declaration"); + cil_destroy_ibpkeycon(ibpkeycon); + + return rc; +} + +void cil_destroy_ibpkeycon(struct cil_ibpkeycon *ibpkeycon) +{ + if (!ibpkeycon) + return; + + if (!ibpkeycon->context_str && ibpkeycon->context) + cil_destroy_context(ibpkeycon->context); + + free(ibpkeycon); +} + +int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_portcon *portcon = NULL; + char *proto; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_portcon_init(&portcon); + + proto = parse_current->next->data; + if (proto == CIL_KEY_UDP) { + portcon->proto = CIL_PROTOCOL_UDP; + } else if (proto == CIL_KEY_TCP) { + portcon->proto = CIL_PROTOCOL_TCP; + } else if (proto == CIL_KEY_DCCP) { + portcon->proto = CIL_PROTOCOL_DCCP; + } else if (proto == CIL_KEY_SCTP) { + portcon->proto = CIL_PROTOCOL_SCTP; + } else { + cil_log(CIL_ERR, "Invalid protocol\n"); + rc = SEPOL_ERR; + goto exit; + } + + if (parse_current->next->next->cl_head != NULL) { + if (parse_current->next->next->cl_head->next != NULL + && parse_current->next->next->cl_head->next->next == NULL) { + rc = cil_fill_integer(parse_current->next->next->cl_head, &portcon->port_low, 10); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper port specified\n"); + goto exit; + } + rc = cil_fill_integer(parse_current->next->next->cl_head->next, &portcon->port_high, 10); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper port specified\n"); + goto exit; + } + } else { + cil_log(CIL_ERR, "Improper port range specified\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_fill_integer(parse_current->next->next, &portcon->port_low, 10); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper port specified\n"); + goto exit; + } + portcon->port_high = portcon->port_low; + } + + if (parse_current->next->next->next->cl_head == NULL ) { + portcon->context_str = parse_current->next->next->next->data; + } else { + cil_context_init(&portcon->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, portcon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = portcon; + ast_node->flavor = CIL_PORTCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad portcon declaration"); + cil_destroy_portcon(portcon); + return rc; +} + +void cil_destroy_portcon(struct cil_portcon *portcon) +{ + if (portcon == NULL) { + return; + } + + if (portcon->context_str == NULL && portcon->context != NULL) { + cil_destroy_context(portcon->context); + } + + free(portcon); +} + +int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_nodecon *nodecon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_nodecon_init(&nodecon); + + if (parse_current->next->cl_head == NULL ) { + nodecon->addr_str = parse_current->next->data; + } else { + cil_ipaddr_init(&nodecon->addr); + + rc = cil_fill_ipaddr(parse_current->next->cl_head, nodecon->addr); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (parse_current->next->next->cl_head == NULL ) { + nodecon->mask_str = parse_current->next->next->data; + } else { + cil_ipaddr_init(&nodecon->mask); + + rc = cil_fill_ipaddr(parse_current->next->next->cl_head, nodecon->mask); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (parse_current->next->next->next->cl_head == NULL ) { + nodecon->context_str = parse_current->next->next->next->data; + } else { + cil_context_init(&nodecon->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, nodecon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = nodecon; + ast_node->flavor = CIL_NODECON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad nodecon declaration"); + cil_destroy_nodecon(nodecon); + return rc; +} + +void cil_destroy_nodecon(struct cil_nodecon *nodecon) +{ + if (nodecon == NULL) { + return; + } + + if (nodecon->addr_str == NULL && nodecon->addr != NULL) { + cil_destroy_ipaddr(nodecon->addr); + } + + if (nodecon->mask_str == NULL && nodecon->mask != NULL) { + cil_destroy_ipaddr(nodecon->mask); + } + + if (nodecon->context_str == NULL && nodecon->context != NULL) { + cil_destroy_context(nodecon->context); + } + + free(nodecon); +} + +int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_tree_node *context_node; + int rc = SEPOL_ERR; + struct cil_genfscon *genfscon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_genfscon_init(&genfscon); + + genfscon->fs_str = parse_current->next->data; + genfscon->path_str = parse_current->next->next->data; + + if (parse_current->next->next->next->next) { + /* (genfscon ... */ + char *file_type = parse_current->next->next->next->data; + if (file_type == CIL_KEY_ANY) { + genfscon->file_type = CIL_FILECON_ANY; + } else if (file_type == CIL_KEY_FILE) { + genfscon->file_type = CIL_FILECON_FILE; + } else if (file_type == CIL_KEY_DIR) { + genfscon->file_type = CIL_FILECON_DIR; + } else if (file_type == CIL_KEY_CHAR) { + genfscon->file_type = CIL_FILECON_CHAR; + } else if (file_type == CIL_KEY_BLOCK) { + genfscon->file_type = CIL_FILECON_BLOCK; + } else if (file_type == CIL_KEY_SOCKET) { + genfscon->file_type = CIL_FILECON_SOCKET; + } else if (file_type == CIL_KEY_PIPE) { + genfscon->file_type = CIL_FILECON_PIPE; + } else if (file_type == CIL_KEY_SYMLINK) { + genfscon->file_type = CIL_FILECON_SYMLINK; + } else { + if (parse_current->next->next->next->cl_head) { + cil_log(CIL_ERR, "Expecting file type, but found a list\n"); + } else { + cil_log(CIL_ERR, "Invalid file type \"%s\"\n", file_type); + } + rc = SEPOL_ERR; + goto exit; + } + context_node = parse_current->next->next->next->next; + } else { + /* (genfscon ... */ + context_node = parse_current->next->next->next; + } + + if (context_node->cl_head) { + cil_context_init(&genfscon->context); + rc = cil_fill_context(context_node->cl_head, genfscon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } else { + genfscon->context_str = context_node->data; + } + + ast_node->data = genfscon; + ast_node->flavor = CIL_GENFSCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad genfscon declaration"); + cil_destroy_genfscon(genfscon); + return SEPOL_ERR; +} + +void cil_destroy_genfscon(struct cil_genfscon *genfscon) +{ + if (genfscon == NULL) { + return; + } + + if (genfscon->context_str == NULL && genfscon->context != NULL) { + cil_destroy_context(genfscon->context); + } + + free(genfscon); +} + + +int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_netifcon *netifcon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_netifcon_init(&netifcon); + + netifcon->interface_str = parse_current->next->data; + + if (parse_current->next->next->cl_head == NULL) { + netifcon->if_context_str = parse_current->next->next->data; + } else { + cil_context_init(&netifcon->if_context); + + rc = cil_fill_context(parse_current->next->next->cl_head, netifcon->if_context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (parse_current->next->next->next->cl_head == NULL) { + netifcon->packet_context_str = parse_current->next->next->next->data; + } else { + cil_context_init(&netifcon->packet_context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, netifcon->packet_context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = netifcon; + ast_node->flavor = CIL_NETIFCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad netifcon declaration"); + cil_destroy_netifcon(netifcon); + return SEPOL_ERR; +} + +void cil_destroy_netifcon(struct cil_netifcon *netifcon) +{ + if (netifcon == NULL) { + return; + } + + if (netifcon->if_context_str == NULL && netifcon->if_context != NULL) { + cil_destroy_context(netifcon->if_context); + } + + if (netifcon->packet_context_str == NULL && netifcon->packet_context != NULL) { + cil_destroy_context(netifcon->packet_context); + } + + free(netifcon); +} + +int cil_gen_ibendportcon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax) / sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_ibendportcon *ibendportcon = NULL; + + if (!parse_current || !ast_node) + goto exit; + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) + goto exit; + + cil_ibendportcon_init(&ibendportcon); + + ibendportcon->dev_name_str = parse_current->next->data; + + rc = cil_fill_integer(parse_current->next->next, &ibendportcon->port, 10); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibendport port specified\n"); + goto exit; + } + + if (!parse_current->next->next->next->cl_head) { + ibendportcon->context_str = parse_current->next->next->next->data; + } else { + cil_context_init(&ibendportcon->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, ibendportcon->context); + if (rc != SEPOL_OK) + goto exit; + } + + ast_node->data = ibendportcon; + ast_node->flavor = CIL_IBENDPORTCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad ibendportcon declaration"); + cil_destroy_ibendportcon(ibendportcon); + return SEPOL_ERR; +} + +void cil_destroy_ibendportcon(struct cil_ibendportcon *ibendportcon) +{ + if (!ibendportcon) + return; + + if (!ibendportcon->context_str && ibendportcon->context) + cil_destroy_context(ibendportcon->context); + + free(ibendportcon); +} + +int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_pirqcon *pirqcon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_pirqcon_init(&pirqcon); + + rc = cil_fill_integer(parse_current->next, &pirqcon->pirq, 10); + if (rc != SEPOL_OK) { + goto exit; + } + + if (parse_current->next->next->cl_head == NULL) { + pirqcon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&pirqcon->context); + + rc = cil_fill_context(parse_current->next->next->cl_head, pirqcon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = pirqcon; + ast_node->flavor = CIL_PIRQCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad pirqcon declaration"); + cil_destroy_pirqcon(pirqcon); + return rc; +} + +void cil_destroy_pirqcon(struct cil_pirqcon *pirqcon) +{ + if (pirqcon == NULL) { + return; + } + + if (pirqcon->context_str == NULL && pirqcon->context != NULL) { + cil_destroy_context(pirqcon->context); + } + + free(pirqcon); +} + +int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_iomemcon *iomemcon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_iomemcon_init(&iomemcon); + + if (parse_current->next->cl_head != NULL) { + if (parse_current->next->cl_head->next != NULL && + parse_current->next->cl_head->next->next == NULL) { + rc = cil_fill_integer64(parse_current->next->cl_head, &iomemcon->iomem_low, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper iomem specified\n"); + goto exit; + } + rc = cil_fill_integer64(parse_current->next->cl_head->next, &iomemcon->iomem_high, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper iomem specified\n"); + goto exit; + } + } else { + cil_log(CIL_ERR, "Improper iomem range specified\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_fill_integer64(parse_current->next, &iomemcon->iomem_low, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper iomem specified\n"); + goto exit; + } + iomemcon->iomem_high = iomemcon->iomem_low; + } + + if (parse_current->next->next->cl_head == NULL ) { + iomemcon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&iomemcon->context); + + rc = cil_fill_context(parse_current->next->next->cl_head, iomemcon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = iomemcon; + ast_node->flavor = CIL_IOMEMCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad iomemcon declaration"); + cil_destroy_iomemcon(iomemcon); + return rc; +} + +void cil_destroy_iomemcon(struct cil_iomemcon *iomemcon) +{ + if (iomemcon == NULL) { + return; + } + + if (iomemcon->context_str == NULL && iomemcon->context != NULL) { + cil_destroy_context(iomemcon->context); + } + + free(iomemcon); +} + +int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_ioportcon *ioportcon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_ioportcon_init(&ioportcon); + + if (parse_current->next->cl_head != NULL) { + if (parse_current->next->cl_head->next != NULL && + parse_current->next->cl_head->next->next == NULL) { + rc = cil_fill_integer(parse_current->next->cl_head, &ioportcon->ioport_low, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ioport specified\n"); + goto exit; + } + rc = cil_fill_integer(parse_current->next->cl_head->next, &ioportcon->ioport_high, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ioport specified\n"); + goto exit; + } + } else { + cil_log(CIL_ERR, "Improper ioport range specified\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_fill_integer(parse_current->next, &ioportcon->ioport_low, 0); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ioport specified\n"); + goto exit; + } + ioportcon->ioport_high = ioportcon->ioport_low; + } + + if (parse_current->next->next->cl_head == NULL ) { + ioportcon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&ioportcon->context); + + rc = cil_fill_context(parse_current->next->next->cl_head, ioportcon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = ioportcon; + ast_node->flavor = CIL_IOPORTCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad ioportcon declaration"); + cil_destroy_ioportcon(ioportcon); + return rc; +} + +void cil_destroy_ioportcon(struct cil_ioportcon *ioportcon) +{ + if (ioportcon == NULL) { + return; + } + + if (ioportcon->context_str == NULL && ioportcon->context != NULL) { + cil_destroy_context(ioportcon->context); + } + + free(ioportcon); +} + +int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_pcidevicecon *pcidevicecon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_pcidevicecon_init(&pcidevicecon); + + rc = cil_fill_integer(parse_current->next, &pcidevicecon->dev, 0); + if (rc != SEPOL_OK) { + goto exit; + } + + if (parse_current->next->next->cl_head == NULL) { + pcidevicecon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&pcidevicecon->context); + + rc = cil_fill_context(parse_current->next->next->cl_head, pcidevicecon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = pcidevicecon; + ast_node->flavor = CIL_PCIDEVICECON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad pcidevicecon declaration"); + cil_destroy_pcidevicecon(pcidevicecon); + return rc; +} + +void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon) +{ + if (pcidevicecon == NULL) { + return; + } + + if (pcidevicecon->context_str == NULL && pcidevicecon->context != NULL) { + cil_destroy_context(pcidevicecon->context); + } + + free(pcidevicecon); +} + +int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_devicetreecon *devicetreecon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_devicetreecon_init(&devicetreecon); + + devicetreecon->path = parse_current->next->data; + + if (parse_current->next->next->cl_head == NULL) { + devicetreecon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&devicetreecon->context); + + rc = cil_fill_context(parse_current->next->next->cl_head, devicetreecon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = devicetreecon; + ast_node->flavor = CIL_DEVICETREECON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad devicetreecon declaration"); + cil_destroy_devicetreecon(devicetreecon); + return rc; +} + +void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon) +{ + if (devicetreecon == NULL) { + return; + } + + if (devicetreecon->context_str == NULL && devicetreecon->context != NULL) { + cil_destroy_context(devicetreecon->context); + } + + free(devicetreecon); +} + +int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *type = NULL; + struct cil_fsuse *fsuse = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + type = parse_current->next->data; + + cil_fsuse_init(&fsuse); + + if (type == CIL_KEY_XATTR) { + fsuse->type = CIL_FSUSE_XATTR; + } else if (type == CIL_KEY_TASK) { + fsuse->type = CIL_FSUSE_TASK; + } else if (type == CIL_KEY_TRANS) { + fsuse->type = CIL_FSUSE_TRANS; + } else { + cil_log(CIL_ERR, "Invalid fsuse type\n"); + goto exit; + } + + fsuse->fs_str = parse_current->next->next->data; + + if (parse_current->next->next->next->cl_head == NULL) { + fsuse->context_str = parse_current->next->next->next->data; + } else { + cil_context_init(&fsuse->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, fsuse->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = fsuse; + ast_node->flavor = CIL_FSUSE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad fsuse declaration"); + cil_destroy_fsuse(fsuse); + return SEPOL_ERR; +} + +void cil_destroy_fsuse(struct cil_fsuse *fsuse) +{ + if (fsuse == NULL) { + return; + } + + if (fsuse->context_str == NULL && fsuse->context != NULL) { + cil_destroy_context(fsuse->context); + } + + free(fsuse); +} + +void cil_destroy_param(struct cil_param *param) +{ + if (param == NULL) { + return; + } + + free(param); +} + +int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + char *key = NULL; + struct cil_macro *macro = NULL; + struct cil_tree_node *macro_content = NULL; + struct cil_tree_node *current_item; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, + CIL_SYN_N_LISTS | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/ sizeof(*syntax); + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc =__cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_macro_init(¯o); + + key = parse_current->next->data; + + current_item = parse_current->next->next->cl_head; + while (current_item != NULL) { + enum cil_syntax param_syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + int param_syntax_len = sizeof(param_syntax)/sizeof(*param_syntax); + char *kind = NULL; + struct cil_param *param = NULL; + struct cil_list_item *curr_param; + + rc =__cil_verify_syntax(current_item->cl_head, param_syntax, param_syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + if (macro->params == NULL) { + cil_list_init(¯o->params, CIL_LIST_ITEM); + } + + kind = current_item->cl_head->data; + cil_param_init(¶m); + + if (kind == CIL_KEY_TYPE) { + param->flavor = CIL_TYPE; + } else if (kind == CIL_KEY_ROLE) { + param->flavor = CIL_ROLE; + } else if (kind == CIL_KEY_USER) { + param->flavor = CIL_USER; + } else if (kind == CIL_KEY_SENSITIVITY) { + param->flavor = CIL_SENS; + } else if (kind == CIL_KEY_CATEGORY) { + param->flavor = CIL_CAT; + } else if (kind == CIL_KEY_CATSET) { + param->flavor = CIL_CATSET; + } else if (kind == CIL_KEY_LEVEL) { + param->flavor = CIL_LEVEL; + } else if (kind == CIL_KEY_LEVELRANGE) { + param->flavor = CIL_LEVELRANGE; + } else if (kind == CIL_KEY_CLASS) { + param->flavor = CIL_CLASS; + } else if (kind == CIL_KEY_IPADDR) { + param->flavor = CIL_IPADDR; + } else if (kind == CIL_KEY_MAP_CLASS) { + param->flavor = CIL_MAP_CLASS; + } else if (kind == CIL_KEY_CLASSPERMISSION) { + param->flavor = CIL_CLASSPERMISSION; + } else if (kind == CIL_KEY_BOOL) { + param->flavor = CIL_BOOL; + } else if (kind == CIL_KEY_STRING) { + param->flavor = CIL_NAME; + } else if (kind == CIL_KEY_NAME) { + param->flavor = CIL_NAME; + } else { + cil_log(CIL_ERR, "The kind %s is not allowed as a parameter\n",kind); + cil_destroy_param(param); + goto exit; + } + + param->str = current_item->cl_head->next->data; + + rc = cil_verify_name(db, param->str, param->flavor); + if (rc != SEPOL_OK) { + cil_destroy_param(param); + goto exit; + } + + //walk current list and check for duplicate parameters + cil_list_for_each(curr_param, macro->params) { + if (param->str == ((struct cil_param*)curr_param->data)->str) { + cil_log(CIL_ERR, "Duplicate parameter\n"); + cil_destroy_param(param); + goto exit; + } + } + + cil_list_append(macro->params, CIL_PARAM, param); + + current_item = current_item->next; + } + + /* we don't want the tree walker to walk the macro parameters (they were just handled above), so the subtree is deleted, and the next pointer of the + node containing the macro name is updated to point to the start of the macro content */ + macro_content = parse_current->next->next->next; + cil_tree_subtree_destroy(parse_current->next->next); + parse_current->next->next = macro_content; + if (macro_content == NULL) { + /* No statements in macro and macro parameter list was last node */ + parse_current->parent->cl_tail = parse_current->next; + } + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)macro, (hashtab_key_t)key, CIL_SYM_BLOCKS, CIL_MACRO); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad macro declaration"); + cil_destroy_macro(macro); + cil_clear_node(ast_node); + return SEPOL_ERR; +} + +void cil_destroy_macro(struct cil_macro *macro) +{ + if (macro == NULL) { + return; + } + + cil_symtab_datum_destroy(¯o->datum); + cil_symtab_array_destroy(macro->symtab); + + if (macro->params != NULL) { + cil_list_destroy(¯o->params, 1); + } + + free(macro); +} + +int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_LIST | CIL_SYN_EMPTY_LIST | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_call *call = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_call_init(&call); + + call->macro_str = parse_current->next->data; + + if (parse_current->next->next != NULL) { + cil_tree_init(&call->args_tree); + cil_copy_ast(db, parse_current->next->next, call->args_tree->root); + } + + ast_node->data = call; + ast_node->flavor = CIL_CALL; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad macro call"); + cil_destroy_call(call); + return rc; +} + +void cil_destroy_call(struct cil_call *call) +{ + if (call == NULL) { + return; + } + + call->macro = NULL; + + if (call->args_tree != NULL) { + cil_tree_destroy(&call->args_tree); + } + + if (call->args != NULL) { + cil_list_destroy(&call->args, 1); + } + + free(call); +} + +void cil_destroy_args(struct cil_args *args) +{ + if (args == NULL) { + return; + } + + if (args->arg_str != NULL) { + args->arg_str = NULL; + } else if (args->arg != NULL) { + struct cil_tree_node *node = args->arg->nodes->head->data; + switch (args->flavor) { + case CIL_NAME: + break; + case CIL_CATSET: + cil_destroy_catset((struct cil_catset *)args->arg); + free(node); + break; + case CIL_LEVEL: + cil_destroy_level((struct cil_level *)args->arg); + free(node); + break; + case CIL_LEVELRANGE: + cil_destroy_levelrange((struct cil_levelrange *)args->arg); + free(node); + break; + case CIL_IPADDR: + cil_destroy_ipaddr((struct cil_ipaddr *)args->arg); + free(node); + break; + case CIL_CLASSPERMISSION: + cil_destroy_classpermission((struct cil_classpermission *)args->arg); + free(node); + break; + default: + cil_log(CIL_ERR, "Destroying arg with the unexpected flavor=%d\n",args->flavor); + break; + } + } + + args->param_str = NULL; + args->arg = NULL; + + free(args); +} + +int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_N_LISTS | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_optional *optional = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_optional_init(&optional); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)optional, (hashtab_key_t)key, CIL_SYM_BLOCKS, CIL_OPTIONAL); + if (rc != SEPOL_OK) { + if (rc == SEPOL_EEXIST) { + cil_destroy_optional(optional); + optional = NULL; + } else { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad optional"); + cil_destroy_optional(optional); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_optional(struct cil_optional *optional) +{ + if (optional == NULL) { + return; + } + + cil_symtab_datum_destroy(&optional->datum); + free(optional); +} + +int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_policycap *polcap = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_policycap_init(&polcap); + + key = parse_current->next->data; + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)polcap, (hashtab_key_t)key, CIL_SYM_POLICYCAPS, CIL_POLICYCAP); + if (rc != SEPOL_OK) + goto exit; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad policycap statement"); + cil_destroy_policycap(polcap); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_policycap(struct cil_policycap *polcap) +{ + if (polcap == NULL) { + return; + } + + cil_symtab_datum_destroy(&polcap->datum); + free(polcap); +} + +int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + char *key = NULL; + struct cil_ipaddr *ipaddr = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_ipaddr_init(&ipaddr); + + key = parse_current->next->data; + + rc = cil_fill_ipaddr(parse_current->next->next, ipaddr); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)ipaddr, (hashtab_key_t)key, CIL_SYM_IPADDRS, CIL_IPADDR); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad ipaddr statement"); + cil_destroy_ipaddr(ipaddr); + cil_clear_node(ast_node); + return rc; +} + +void cil_destroy_ipaddr(struct cil_ipaddr *ipaddr) +{ + if (ipaddr == NULL) { + return; + } + + cil_symtab_datum_destroy(&ipaddr->datum); + free(ipaddr); +} + +int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer, int base) +{ + int rc = SEPOL_ERR; + + if (int_node == NULL || int_node->data == NULL || integer == NULL) { + goto exit; + } + + rc = cil_string_to_uint32(int_node->data, integer, base); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to fill 32-bit integer\n"); + return rc; +} + +int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer, int base) +{ + int rc = SEPOL_ERR; + + if (int_node == NULL || int_node->data == NULL || integer == NULL) { + goto exit; + } + + rc = cil_string_to_uint64(int_node->data, integer, base); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Failed to fill 64-bit integer\n"); + return rc; +} + +int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr) +{ + int rc = SEPOL_ERR; + + if (addr_node == NULL || addr_node->data == NULL || addr == NULL) { + goto exit; + } + + if (strchr(addr_node->data, ':') != NULL) { + addr->family = AF_INET6; + } else { + addr->family = AF_INET; + } + + rc = inet_pton(addr->family, addr_node->data, &addr->ip); + if (rc != 1) { + rc = SEPOL_ERR; + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad ip address or netmask: %s\n", (addr_node && addr_node->data) ? (const char *)addr_node->data : "n/a"); + return rc; +} + +int cil_fill_level(struct cil_tree_node *curr, struct cil_level *level) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + if (curr == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(curr, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + level->sens_str = curr->data; + if (curr->next != NULL) { + rc = cil_fill_cats(curr->next, &level->cats); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad level\n"); + return rc; +} + +int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats) +{ + int rc = SEPOL_ERR; + + cil_cats_init(cats); + + rc = cil_gen_expr(curr, CIL_CAT, &(*cats)->str_expr); + if (rc != SEPOL_OK) { + cil_destroy_cats(*cats); + *cats = NULL; + } + + return rc; +} + +void cil_destroy_cats(struct cil_cats *cats) +{ + if (cats == NULL) { + return; + } + + cil_list_destroy(&cats->str_expr, CIL_TRUE); + + cil_list_destroy(&cats->datum_expr, CIL_FALSE); + + free(cats); +} +int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_bounds *bounds = NULL; + int rc = SEPOL_ERR; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_bounds_init(&bounds); + + bounds->parent_str = parse_current->next->data; + bounds->child_str = parse_current->next->next->data; + + ast_node->data = bounds; + + switch (flavor) { + case CIL_USER: + ast_node->flavor = CIL_USERBOUNDS; + break; + case CIL_ROLE: + ast_node->flavor = CIL_ROLEBOUNDS; + break; + case CIL_TYPE: + ast_node->flavor = CIL_TYPEBOUNDS; + break; + default: + break; + } + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad bounds declaration"); + cil_destroy_bounds(bounds); + return rc; +} + +void cil_destroy_bounds(struct cil_bounds *bounds) +{ + if (bounds == NULL) { + return; + } + + free(bounds); +} + +int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor) +{ + int rc = SEPOL_ERR; + struct cil_default *def = NULL; + char *object; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_default_init(&def); + + def->flavor = flavor; + + if (parse_current->next->cl_head == NULL) { + cil_list_init(&def->class_strs, CIL_CLASS); + cil_list_append(def->class_strs, CIL_STRING, parse_current->next->data); + } else { + rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); + if (rc != SEPOL_OK) { + goto exit; + } + } + + object = parse_current->next->next->data; + if (object == CIL_KEY_SOURCE) { + def->object = CIL_DEFAULT_SOURCE; + } else if (object == CIL_KEY_TARGET) { + def->object = CIL_DEFAULT_TARGET; + } else { + cil_log(CIL_ERR,"Expected either 'source' or 'target'\n"); + rc = SEPOL_ERR; + goto exit; + } + + ast_node->data = def; + ast_node->flavor = flavor; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", cil_node_to_string(parse_current)); + cil_destroy_default(def); + return rc; +} + +void cil_destroy_default(struct cil_default *def) +{ + if (def == NULL) { + return; + } + + cil_list_destroy(&def->class_strs, CIL_TRUE); + + cil_list_destroy(&def->class_datums, CIL_FALSE); + + free(def); +} + +int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + struct cil_defaultrange *def = NULL; + char *object; + char *range; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_defaultrange_init(&def); + + if (parse_current->next->cl_head == NULL) { + cil_list_init(&def->class_strs, CIL_CLASS); + cil_list_append(def->class_strs, CIL_STRING, parse_current->next->data); + } else { + rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); + if (rc != SEPOL_OK) { + goto exit; + } + } + + object = parse_current->next->next->data; + if (object == CIL_KEY_SOURCE) { + if (!parse_current->next->next->next) { + cil_log(CIL_ERR, "Missing 'low', 'high', or 'low-high'\n"); + rc = SEPOL_ERR; + goto exit; + } + range = parse_current->next->next->next->data; + if (range == CIL_KEY_LOW) { + def->object_range = CIL_DEFAULT_SOURCE_LOW; + } else if (range == CIL_KEY_HIGH) { + def->object_range = CIL_DEFAULT_SOURCE_HIGH; + } else if (range == CIL_KEY_LOW_HIGH) { + def->object_range = CIL_DEFAULT_SOURCE_LOW_HIGH; + } else { + cil_log(CIL_ERR,"Expected 'low', 'high', or 'low-high'\n"); + rc = SEPOL_ERR; + goto exit; + } + } else if (object == CIL_KEY_TARGET) { + if (!parse_current->next->next->next) { + cil_log(CIL_ERR, "Missing 'low', 'high', or 'low-high'\n"); + rc = SEPOL_ERR; + goto exit; + } + range = parse_current->next->next->next->data; + if (range == CIL_KEY_LOW) { + def->object_range = CIL_DEFAULT_TARGET_LOW; + } else if (range == CIL_KEY_HIGH) { + def->object_range = CIL_DEFAULT_TARGET_HIGH; + } else if (range == CIL_KEY_LOW_HIGH) { + def->object_range = CIL_DEFAULT_TARGET_LOW_HIGH; + } else { + cil_log(CIL_ERR,"Expected 'low', 'high', or 'low-high'\n"); + rc = SEPOL_ERR; + goto exit; + } + } else if (object == CIL_KEY_GLBLUB) { + def->object_range = CIL_DEFAULT_GLBLUB; + } else { + cil_log(CIL_ERR,"Expected \'source\', \'target\', or \'glblub\'\n"); + rc = SEPOL_ERR; + goto exit; + } + + ast_node->data = def; + ast_node->flavor = CIL_DEFAULTRANGE; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad defaultrange declaration"); + cil_destroy_defaultrange(def); + return rc; +} + +void cil_destroy_defaultrange(struct cil_defaultrange *def) +{ + if (def == NULL) { + return; + } + + cil_list_destroy(&def->class_strs, CIL_TRUE); + + cil_list_destroy(&def->class_datums, CIL_FALSE); + + free(def); +} + +int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_handleunknown *unknown = NULL; + char *unknown_key; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_handleunknown_init(&unknown); + + unknown_key = parse_current->next->data; + if (unknown_key == CIL_KEY_HANDLEUNKNOWN_ALLOW) { + unknown->handle_unknown = SEPOL_ALLOW_UNKNOWN; + } else if (unknown_key == CIL_KEY_HANDLEUNKNOWN_DENY) { + unknown->handle_unknown = SEPOL_DENY_UNKNOWN; + } else if (unknown_key == CIL_KEY_HANDLEUNKNOWN_REJECT) { + unknown->handle_unknown = SEPOL_REJECT_UNKNOWN; + } else { + cil_log(CIL_ERR, "Expected either \'%s\', \'%s\', or \'%s\'\n", CIL_KEY_HANDLEUNKNOWN_ALLOW, CIL_KEY_HANDLEUNKNOWN_DENY, CIL_KEY_HANDLEUNKNOWN_REJECT); + rc = SEPOL_ERR; + goto exit; + } + + ast_node->data = unknown; + ast_node->flavor = CIL_HANDLEUNKNOWN; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad handleunknown"); + cil_destroy_handleunknown(unknown); + return rc; +} + +void cil_destroy_handleunknown(struct cil_handleunknown *unk) +{ + free(unk); +} + +int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_mls *mls = NULL; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_mls_init(&mls); + + if (parse_current->next->data == CIL_KEY_CONDTRUE) { + mls->value = CIL_TRUE; + } else if (parse_current->next->data == CIL_KEY_CONDFALSE) { + mls->value = CIL_FALSE; + } else { + cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); + rc = SEPOL_ERR; + goto exit; + } + + ast_node->data = mls; + ast_node->flavor = CIL_MLS; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad mls"); + cil_destroy_mls(mls); + return rc; +} + +void cil_destroy_mls(struct cil_mls *mls) +{ + free(mls); +} + +int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + int rc = SEPOL_ERR; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_N_LISTS | CIL_SYN_END, + CIL_SYN_END + }; + size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + struct cil_src_info *info = NULL; + + if (parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_src_info_init(&info); + + info->kind = parse_current->next->data; + if (info->kind != CIL_KEY_SRC_CIL && info->kind != CIL_KEY_SRC_HLL_LMS && info->kind != CIL_KEY_SRC_HLL_LMX) { + cil_log(CIL_ERR, "Invalid src info kind\n"); + rc = SEPOL_ERR; + goto exit; + } + + rc = cil_string_to_uint32(parse_current->next->next->data, &info->hll_line, 10); + if (rc != SEPOL_OK) { + goto exit; + } + + info->path = parse_current->next->next->next->data; + + ast_node->data = info; + ast_node->flavor = CIL_SRC_INFO; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad src info"); + cil_destroy_src_info(info); + return rc; +} + +void cil_destroy_src_info(struct cil_src_info *info) +{ + free(info); +} + +static int check_for_illegal_statement(struct cil_tree_node *parse_current, struct cil_args_build *args) +{ + if (args->tunif != NULL) { + if (parse_current->data == CIL_KEY_TUNABLE) { + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif", (char *)parse_current->data); + return SEPOL_ERR; + } + } + + if (args->in != NULL) { + struct cil_in *in_block = args->in->data; + if (parse_current->data == CIL_KEY_TUNABLE || + parse_current->data == CIL_KEY_IN) { + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in in-statement", (char *)parse_current->data); + return SEPOL_ERR; + } + if (in_block->is_after == CIL_TRUE) { + if (parse_current->data == CIL_KEY_BLOCKINHERIT || + parse_current->data == CIL_KEY_BLOCKABSTRACT) { + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in an after in-statement", (char *)parse_current->data); + return SEPOL_ERR; + } + } + } + + if (args->macro != NULL) { + if (parse_current->data == CIL_KEY_TUNABLE || + parse_current->data == CIL_KEY_IN || + parse_current->data == CIL_KEY_BLOCK || + parse_current->data == CIL_KEY_BLOCKINHERIT || + parse_current->data == CIL_KEY_BLOCKABSTRACT || + parse_current->data == CIL_KEY_MACRO) { + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macro", (char *)parse_current->data); + return SEPOL_ERR; + } + } + + if (args->optional != NULL) { + if (parse_current->data == CIL_KEY_TUNABLE || + parse_current->data == CIL_KEY_IN || + parse_current->data == CIL_KEY_BLOCK || + parse_current->data == CIL_KEY_BLOCKABSTRACT || + parse_current->data == CIL_KEY_MACRO) { + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in optional", (char *)parse_current->data); + return SEPOL_ERR; + } + } + + if (args->boolif != NULL) { + if (parse_current->data != CIL_KEY_TUNABLEIF && + parse_current->data != CIL_KEY_CALL && + parse_current->data != CIL_KEY_CONDTRUE && + parse_current->data != CIL_KEY_CONDFALSE && + parse_current->data != CIL_KEY_ALLOW && + parse_current->data != CIL_KEY_DONTAUDIT && + parse_current->data != CIL_KEY_AUDITALLOW && + parse_current->data != CIL_KEY_TYPETRANSITION && + parse_current->data != CIL_KEY_TYPECHANGE && + parse_current->data != CIL_KEY_TYPEMEMBER) { + if (((struct cil_booleanif*)args->boolif->data)->preserved_tunable) { + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", (char *)parse_current->data); + } else { + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in booleanif", (char *)parse_current->data); + } + return SEPOL_ERR; + } + } + + return SEPOL_OK; +} + +static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_parent) +{ + struct cil_tree_node *new_ast_node = NULL; + int rc = SEPOL_ERR; + + cil_tree_node_init(&new_ast_node); + new_ast_node->parent = ast_parent; + new_ast_node->line = parse_current->line; + new_ast_node->hll_offset = parse_current->hll_offset; + + if (parse_current->data == CIL_KEY_BLOCK) { + rc = cil_gen_block(db, parse_current, new_ast_node, 0); + } else if (parse_current->data == CIL_KEY_BLOCKINHERIT) { + rc = cil_gen_blockinherit(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_BLOCKABSTRACT) { + rc = cil_gen_blockabstract(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_IN) { + rc = cil_gen_in(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CLASS) { + rc = cil_gen_class(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CLASSORDER) { + rc = cil_gen_classorder(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_MAP_CLASS) { + rc = cil_gen_map_class(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CLASSMAPPING) { + rc = cil_gen_classmapping(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CLASSPERMISSION) { + rc = cil_gen_classpermission(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CLASSPERMISSIONSET) { + rc = cil_gen_classpermissionset(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_COMMON) { + rc = cil_gen_common(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CLASSCOMMON) { + rc = cil_gen_classcommon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SID) { + rc = cil_gen_sid(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SIDCONTEXT) { + rc = cil_gen_sidcontext(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SIDORDER) { + rc = cil_gen_sidorder(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_USER) { + rc = cil_gen_user(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_USERATTRIBUTE) { + rc = cil_gen_userattribute(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_USERATTRIBUTESET) { + rc = cil_gen_userattributeset(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_USERLEVEL) { + rc = cil_gen_userlevel(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_USERRANGE) { + rc = cil_gen_userrange(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_USERBOUNDS) { + rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_USER); + } else if (parse_current->data == CIL_KEY_USERPREFIX) { + rc = cil_gen_userprefix(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SELINUXUSER) { + rc = cil_gen_selinuxuser(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SELINUXUSERDEFAULT) { + rc = cil_gen_selinuxuserdefault(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_TYPE) { + rc = cil_gen_type(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTE) { + rc = cil_gen_typeattribute(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTESET) { + rc = cil_gen_typeattributeset(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_EXPANDTYPEATTRIBUTE) { + rc = cil_gen_expandtypeattribute(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_TYPEALIAS) { + rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_TYPEALIAS); + } else if (parse_current->data == CIL_KEY_TYPEALIASACTUAL) { + rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_TYPEALIASACTUAL); + } else if (parse_current->data == CIL_KEY_TYPEBOUNDS) { + rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_TYPE); + } else if (parse_current->data == CIL_KEY_TYPEPERMISSIVE) { + rc = cil_gen_typepermissive(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_RANGETRANSITION) { + rc = cil_gen_rangetransition(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_ROLE) { + rc = cil_gen_role(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_USERROLE) { + rc = cil_gen_userrole(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_ROLETYPE) { + rc = cil_gen_roletype(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_ROLETRANSITION) { + rc = cil_gen_roletransition(parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_ROLEALLOW) { + rc = cil_gen_roleallow(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTE) { + rc = cil_gen_roleattribute(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTESET) { + rc = cil_gen_roleattributeset(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_ROLEBOUNDS) { + rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_ROLE); + } else if (parse_current->data == CIL_KEY_BOOL) { + rc = cil_gen_bool(db, parse_current, new_ast_node, CIL_FALSE); + } else if (parse_current->data == CIL_KEY_BOOLEANIF) { + rc = cil_gen_boolif(db, parse_current, new_ast_node, CIL_FALSE); + } else if(parse_current->data == CIL_KEY_TUNABLE) { + if (db->preserve_tunables) { + rc = cil_gen_bool(db, parse_current, new_ast_node, CIL_TRUE); + } else { + rc = cil_gen_tunable(db, parse_current, new_ast_node); + } + } else if (parse_current->data == CIL_KEY_TUNABLEIF) { + if (db->preserve_tunables) { + rc = cil_gen_boolif(db, parse_current, new_ast_node, CIL_TRUE); + } else { + rc = cil_gen_tunif(db, parse_current, new_ast_node); + } + } else if (parse_current->data == CIL_KEY_CONDTRUE) { + rc = cil_gen_condblock(db, parse_current, new_ast_node, CIL_CONDTRUE); + } else if (parse_current->data == CIL_KEY_CONDFALSE) { + rc = cil_gen_condblock(db, parse_current, new_ast_node, CIL_CONDFALSE); + } else if (parse_current->data == CIL_KEY_ALLOW) { + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_ALLOWED); + } else if (parse_current->data == CIL_KEY_AUDITALLOW) { + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_AUDITALLOW); + } else if (parse_current->data == CIL_KEY_DONTAUDIT) { + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_DONTAUDIT); + } else if (parse_current->data == CIL_KEY_NEVERALLOW) { + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_NEVERALLOW); + } else if (parse_current->data == CIL_KEY_ALLOWX) { + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_ALLOWED); + } else if (parse_current->data == CIL_KEY_AUDITALLOWX) { + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_AUDITALLOW); + } else if (parse_current->data == CIL_KEY_DONTAUDITX) { + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_DONTAUDIT); + } else if (parse_current->data == CIL_KEY_NEVERALLOWX) { + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_NEVERALLOW); + } else if (parse_current->data == CIL_KEY_PERMISSIONX) { + rc = cil_gen_permissionx(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_TYPETRANSITION) { + rc = cil_gen_typetransition(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_TYPECHANGE) { + rc = cil_gen_type_rule(parse_current, new_ast_node, CIL_TYPE_CHANGE); + } else if (parse_current->data == CIL_KEY_TYPEMEMBER) { + rc = cil_gen_type_rule(parse_current, new_ast_node, CIL_TYPE_MEMBER); + } else if (parse_current->data == CIL_KEY_SENSITIVITY) { + rc = cil_gen_sensitivity(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SENSALIAS) { + rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_SENSALIAS); + } else if (parse_current->data == CIL_KEY_SENSALIASACTUAL) { + rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_SENSALIASACTUAL); + } else if (parse_current->data == CIL_KEY_CATEGORY) { + rc = cil_gen_category(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CATALIAS) { + rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_CATALIAS); + } else if (parse_current->data == CIL_KEY_CATALIASACTUAL) { + rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_CATALIASACTUAL); + } else if (parse_current->data == CIL_KEY_CATSET) { + rc = cil_gen_catset(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CATORDER) { + rc = cil_gen_catorder(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SENSITIVITYORDER) { + rc = cil_gen_sensitivityorder(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SENSCAT) { + rc = cil_gen_senscat(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_LEVEL) { + rc = cil_gen_level(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_LEVELRANGE) { + rc = cil_gen_levelrange(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CONSTRAIN) { + rc = cil_gen_constrain(db, parse_current, new_ast_node, CIL_CONSTRAIN); + } else if (parse_current->data == CIL_KEY_MLSCONSTRAIN) { + rc = cil_gen_constrain(db, parse_current, new_ast_node, CIL_MLSCONSTRAIN); + } else if (parse_current->data == CIL_KEY_VALIDATETRANS) { + rc = cil_gen_validatetrans(db, parse_current, new_ast_node, CIL_VALIDATETRANS); + } else if (parse_current->data == CIL_KEY_MLSVALIDATETRANS) { + rc = cil_gen_validatetrans(db, parse_current, new_ast_node, CIL_MLSVALIDATETRANS); + } else if (parse_current->data == CIL_KEY_CONTEXT) { + rc = cil_gen_context(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_FILECON) { + rc = cil_gen_filecon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_IBPKEYCON) { + rc = cil_gen_ibpkeycon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_IBENDPORTCON) { + rc = cil_gen_ibendportcon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_PORTCON) { + rc = cil_gen_portcon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_NODECON) { + rc = cil_gen_nodecon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_GENFSCON) { + rc = cil_gen_genfscon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_NETIFCON) { + rc = cil_gen_netifcon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_PIRQCON) { + rc = cil_gen_pirqcon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_IOMEMCON) { + rc = cil_gen_iomemcon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_IOPORTCON) { + rc = cil_gen_ioportcon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_PCIDEVICECON) { + rc = cil_gen_pcidevicecon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_DEVICETREECON) { + rc = cil_gen_devicetreecon(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_FSUSE) { + rc = cil_gen_fsuse(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_MACRO) { + rc = cil_gen_macro(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_CALL) { + rc = cil_gen_call(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_POLICYCAP) { + rc = cil_gen_policycap(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_OPTIONAL) { + rc = cil_gen_optional(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_IPADDR) { + rc = cil_gen_ipaddr(db, parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_DEFAULTUSER) { + rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTUSER); + } else if (parse_current->data == CIL_KEY_DEFAULTROLE) { + rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTROLE); + } else if (parse_current->data == CIL_KEY_DEFAULTTYPE) { + rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTTYPE); + } else if (parse_current->data == CIL_KEY_DEFAULTRANGE) { + rc = cil_gen_defaultrange(parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_HANDLEUNKNOWN) { + rc = cil_gen_handleunknown(parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_MLS) { + rc = cil_gen_mls(parse_current, new_ast_node); + } else if (parse_current->data == CIL_KEY_SRC_INFO) { + rc = cil_gen_src_info(parse_current, new_ast_node); + } else { + cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char *)parse_current->data); + rc = SEPOL_ERR; + } + + if (rc == SEPOL_OK) { + if (ast_parent->cl_head == NULL) { + ast_parent->cl_head = new_ast_node; + } else { + ast_parent->cl_tail->next = new_ast_node; + } + ast_parent->cl_tail = new_ast_node; + } else { + cil_tree_node_destroy(&new_ast_node); + new_ast_node = NULL; + } + + return new_ast_node; +} + +static int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) +{ + struct cil_args_build *args = extra_args; + struct cil_tree_node *new_ast_node = NULL; + int rc = SEPOL_ERR; + + if (parse_current->parent->cl_head != parse_current) { + /* ignore anything that isn't following a parenthesis */ + return SEPOL_OK; + } else if (parse_current->data == NULL) { + /* the only time parenthesis can immediately following parenthesis is if + * the parent is the root node */ + if (parse_current->parent->parent == NULL) { + return SEPOL_OK; + } else { + cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis"); + return SEPOL_ERR; + } + } + + rc = check_for_illegal_statement(parse_current, args); + if (rc != SEPOL_OK) { + return SEPOL_ERR; + } + + new_ast_node = parse_statement(args->db, parse_current, args->ast); + if (!new_ast_node) { + return SEPOL_ERR; + } + + args->ast = new_ast_node; + + if (parse_current->data != CIL_KEY_BLOCK && + parse_current->data != CIL_KEY_IN && + parse_current->data != CIL_KEY_TUNABLEIF && + parse_current->data != CIL_KEY_BOOLEANIF && + parse_current->data != CIL_KEY_CONDTRUE && + parse_current->data != CIL_KEY_CONDFALSE && + parse_current->data != CIL_KEY_MACRO && + parse_current->data != CIL_KEY_OPTIONAL && + parse_current->data != CIL_KEY_SRC_INFO) { + /* Skip anything that does not contain a list of policy statements */ + *finished = CIL_TREE_SKIP_NEXT; + } + + return SEPOL_OK; +} + +static int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_node *parse_current, void *extra_args) +{ + struct cil_args_build *args = extra_args; + struct cil_tree_node *ast = args->ast; + + if (ast->flavor == CIL_TUNABLEIF) { + args->tunif = ast; + } else if (ast->flavor == CIL_IN) { + args->in = ast; + } else if (ast->flavor == CIL_MACRO) { + args->macro = ast; + } else if (ast->flavor == CIL_OPTIONAL) { + args->optional = ast; + } else if (ast->flavor == CIL_BOOLEANIF) { + args->boolif = ast; + } + + return SEPOL_OK; +} + +static int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) +{ + struct cil_args_build *args = extra_args; + struct cil_tree_node *ast = args->ast; + + if (ast->flavor == CIL_ROOT) { + return SEPOL_OK; + } + + args->ast = ast->parent; + + if (ast->flavor == CIL_TUNABLEIF) { + args->tunif = NULL; + } + + if (ast->flavor == CIL_IN) { + args->in = NULL; + } + + if (ast->flavor == CIL_MACRO) { + args->macro = NULL; + } + + if (ast->flavor == CIL_OPTIONAL) { + struct cil_tree_node *n = ast->parent; + args->optional = NULL; + /* Optionals can be nested */ + while (n && n->flavor != CIL_ROOT) { + if (n->flavor == CIL_OPTIONAL) { + args->optional = n; + break; + } + n = n->parent; + } + } + + if (ast->flavor == CIL_BOOLEANIF) { + args->boolif = NULL; + } + + // At this point we no longer have any need for parse_current or any of its + // siblings; they have all been converted to the appropriate AST node. The + // full parse tree will get deleted elsewhere, but in an attempt to + // minimize memory usage (of which the parse tree uses a lot), start + // deleting the parts we don't need now. + cil_tree_children_destroy(parse_current->parent); + + return SEPOL_OK; +} + +int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct cil_tree_node *ast) +{ + int rc = SEPOL_ERR; + struct cil_args_build extra_args; + + if (db == NULL || parse_tree == NULL || ast == NULL) { + goto exit; + } + + extra_args.ast = ast; + extra_args.db = db; + extra_args.tunif = NULL; + extra_args.in = NULL; + extra_args.macro = NULL; + extra_args.optional = NULL; + extra_args.boolif = NULL; + + rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, __cil_build_ast_first_child_helper, __cil_build_ast_last_child_helper, &extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} diff --git a/kernel/libsepol/cil/src/cil_build_ast.h b/kernel/libsepol/cil/src/cil_build_ast.h new file mode 100644 index 00000000..fd9053ce --- /dev/null +++ b/kernel/libsepol/cil/src/cil_build_ast.h @@ -0,0 +1,239 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_BUILD_AST_H_ +#define CIL_BUILD_AST_H_ + +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_tree.h" +#include "cil_list.h" + +int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node); + +int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor); +int cil_parse_to_list(struct cil_tree_node *parse_cl_head, struct cil_list *ast_cl, enum cil_flavor flavor); + +int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint16_t is_abstract); +void cil_destroy_block(struct cil_block *block); +int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_blockinherit(struct cil_blockinherit *inherit); +int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_blockabstract(struct cil_blockabstract *abstract); +int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_in(struct cil_in *in); +int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_class(struct cil_class *class); +int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_classorder(struct cil_classorder *classorder); +int cil_gen_perm(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms); +void cil_destroy_perm(struct cil_perm *perm); +int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms); +int cil_fill_perms(struct cil_tree_node *start_perm, struct cil_list **perm_strs); +int cil_fill_classperms(struct cil_tree_node *parse_current, struct cil_classperms **cp); +void cil_destroy_classperms(struct cil_classperms *cp); +void cil_fill_classperms_set(struct cil_tree_node *parse_current, struct cil_classperms_set **cp_set); +void cil_destroy_classperms_set(struct cil_classperms_set *cp_set); +int cil_fill_classperms_list(struct cil_tree_node *parse_current, struct cil_list **expr_list); +void cil_destroy_classperms_list(struct cil_list **cp_list); +int cil_gen_classpermission(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_classpermission(struct cil_classpermission *cp); +int cil_gen_classpermissionset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_classpermissionset(struct cil_classpermissionset *cps); +int cil_gen_map_class(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +int cil_gen_classmapping(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_classmapping(struct cil_classmapping *mapping); +int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +int cil_gen_classcommon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_classcommon(struct cil_classcommon *clscom); +int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_sid(struct cil_sid *sid); +int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_sidcontext(struct cil_sidcontext *sidcon); +int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_sidorder(struct cil_sidorder *sidorder); +int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_user(struct cil_user *user); +int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_userattribute(struct cil_userattribute *attr); +int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_userattributeset(struct cil_userattributeset *attrset); +int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_userlevel(struct cil_userlevel *usrlvl); +int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_userrange(struct cil_userrange *userrange); +int cil_gen_userbounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +int cil_gen_userprefix(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_userprefix(struct cil_userprefix *userprefix); +int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_selinuxuser(struct cil_selinuxuser *selinuxuser); +int cil_gen_role(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_role(struct cil_role *role); +int cil_gen_roletype(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_roletype(struct cil_roletype *roletype); +int cil_gen_userrole(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_userrole(struct cil_userrole *userrole); +int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_roletransition(struct cil_roletransition *roletrans); +int cil_gen_roleallow(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_roleallow(struct cil_roleallow *roleallow); +int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_roleattribute(struct cil_roleattribute *role); +int cil_gen_roleattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_roleattributeset(struct cil_roleattributeset *attrset); +int cil_gen_rolebounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind); +void cil_destroy_avrule(struct cil_avrule *rule); +int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind); +int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_permissionx(struct cil_permissionx *permx); +int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind); +void cil_destroy_type_rule(struct cil_type_rule *rule); +int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_type(struct cil_type *type); +int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_typeattribute(struct cil_typeattribute *type); +int cil_gen_bool(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, int tunableif); +void cil_destroy_bool(struct cil_bool *boolean); +int cil_gen_tunable(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_tunable(struct cil_tunable *tunable); +int cil_gen_constrain_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **stack); +int cil_gen_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **stack); +int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, int tunable_if); +void cil_destroy_boolif(struct cil_booleanif *bif); +int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_tunif(struct cil_tunableif *tif); +int cil_gen_condblock(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor); +void cil_destroy_condblock(struct cil_condblock *cb); +int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor); +void cil_destroy_alias(struct cil_alias *alias); +int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor); +void cil_destroy_aliasactual(struct cil_aliasactual *aliasactual); +int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_typeattributeset(struct cil_typeattributeset *attrtypes); +int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_expandtypeattribute(struct cil_expandtypeattribute *expandattr); +int cil_gen_typebounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_typepermissive(struct cil_typepermissive *typeperm); +int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_name(struct cil_name *name); +void cil_destroy_typetransition(struct cil_nametypetransition *nametypetrans); +int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_rangetransition(struct cil_rangetransition *rangetrans); +int cil_gen_sensitivity(struct cil_db *idb, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_sensitivity(struct cil_sens *sens); +int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_category(struct cil_cat *cat); +int cil_set_to_list(struct cil_tree_node *parse_current, struct cil_list *ast_cl); +void cil_destroy_catset(struct cil_catset *catset); +int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_catorder(struct cil_catorder *catorder); +int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_sensitivityorder(struct cil_sensorder *sensorder); +int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_senscat(struct cil_senscat *senscat); +int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_level(struct cil_level *level); +int cil_fill_levelrange(struct cil_tree_node *low, struct cil_levelrange *lvlrange); +int cil_gen_levelrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_levelrange(struct cil_levelrange *lvlrange); +void cil_destroy_constrain_node(struct cil_tree_node *cons_node); +int cil_gen_constrain(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor); +void cil_destroy_constrain(struct cil_constrain *cons); +int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor); +void cil_destroy_validatetrans(struct cil_validatetrans *validtrans); +int cil_fill_context(struct cil_tree_node *user_node, struct cil_context *context); +int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_context(struct cil_context *context); +int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_filecon(struct cil_filecon *filecon); +int cil_gen_ibpkeycon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_ibpkeycon(struct cil_ibpkeycon *ibpkeycon); +int cil_gen_ibendportcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_ibendportcon(struct cil_ibendportcon *ibendportcon); +int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_portcon(struct cil_portcon *portcon); +int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_nodecon(struct cil_nodecon *nodecon); +int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_genfscon(struct cil_genfscon *genfscon); +int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_netifcon(struct cil_netifcon *netifcon); +int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_pirqcon(struct cil_pirqcon *pirqcon); +int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_iomemcon(struct cil_iomemcon *iomemcon); +int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_ioportcon(struct cil_ioportcon *ioportcon); +int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon); +int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon); +int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_fsuse(struct cil_fsuse *fsuse); +void cil_destroy_param(struct cil_param *param); +int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_macro(struct cil_macro *macro); +int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_call(struct cil_call *call); +void cil_destroy_args(struct cil_args *args); +int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_optional(struct cil_optional *optional); +int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_policycap(struct cil_policycap *polcap); +int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_ipaddr(struct cil_ipaddr *ipaddr); +int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor); +void cil_destroy_bounds(struct cil_bounds *bounds); +int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor); +void cil_destroy_default(struct cil_default *def); +int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_handleunknown(struct cil_handleunknown *unk); +int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_mls(struct cil_mls *mls); +int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_defaultrange(struct cil_defaultrange *def); +int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_src_info(struct cil_src_info *info); + +int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats); +void cil_destroy_cats(struct cil_cats *cats); +int cil_fill_context(struct cil_tree_node *user_node, struct cil_context *context); +int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer, int base); +int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer, int base); +int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr); +int cil_fill_level(struct cil_tree_node *sens, struct cil_level *level); + +int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct cil_tree_node *ast); + +#endif /* CIL_BUILD_AST_H_ */ diff --git a/kernel/libsepol/cil/src/cil_copy_ast.c b/kernel/libsepol/cil/src/cil_copy_ast.c new file mode 100644 index 00000000..17f05021 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_copy_ast.c @@ -0,0 +1,2144 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include + +#include "cil_internal.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_symtab.h" +#include "cil_copy_ast.h" +#include "cil_build_ast.h" +#include "cil_strpool.h" +#include "cil_verify.h" + +struct cil_args_copy { + struct cil_tree_node *orig_dest; + struct cil_tree_node *dest; + struct cil_db *db; +}; + +void cil_copy_list(struct cil_list *data, struct cil_list **copy) +{ + struct cil_list *new; + struct cil_list_item *orig_item; + + cil_list_init(&new, data->flavor); + + cil_list_for_each(orig_item, data) { + switch (orig_item->flavor) { + case CIL_STRING: + cil_list_append(new, CIL_STRING, orig_item->data); + break; + case CIL_LIST: { + struct cil_list *new_sub = NULL; + cil_copy_list((struct cil_list*)orig_item->data, &new_sub); + cil_list_append(new, CIL_LIST, new_sub); + break; + } + case CIL_PARAM: { + struct cil_param *po = orig_item->data; + struct cil_param *pn; + cil_param_init(&pn); + pn->str = po->str; + pn->flavor = po->flavor; + cil_list_append(new, CIL_PARAM, pn); + } + break; + + default: + cil_list_append(new, orig_item->flavor, orig_item->data); + break; + } + } + + *copy = new; +} + +static int cil_copy_node(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + char *new = NULL; + + if (data != NULL) { + new = data; + } + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_block *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + if (FLAVOR(datum) != CIL_BLOCK) { + cil_tree_log(NODE(orig), CIL_ERR, "Block %s being copied", key); + cil_tree_log(NODE(datum), CIL_ERR, " Conflicts with %s already declared", cil_node_to_string(NODE(datum))); + return SEPOL_ERR; + } + cil_tree_log(NODE(orig), CIL_WARN, "Block %s being copied", key); + cil_tree_log(NODE(datum), CIL_WARN, " Previously declared"); + *copy = datum; + } else { + struct cil_block *new; + cil_block_init(&new); + *copy = new; + } + + return SEPOL_OK; +} + +int cil_copy_blockabstract(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_blockabstract *orig = data; + struct cil_blockabstract *new = NULL; + + cil_blockabstract_init(&new); + + new->block_str = orig->block_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_blockinherit(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_blockinherit *orig = data; + struct cil_blockinherit *new = NULL; + + cil_blockinherit_init(&new); + + new->block_str = orig->block_str; + new->block = orig->block; + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_policycap(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_policycap *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_policycap *new; + cil_policycap_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +int cil_copy_perm(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_perm *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_perm *new; + cil_perm_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +void cil_copy_classperms(struct cil_classperms *orig, struct cil_classperms **new) +{ + cil_classperms_init(new); + (*new)->class_str = orig->class_str; + cil_copy_list(orig->perm_strs, &((*new)->perm_strs)); +} + +void cil_copy_classperms_set(struct cil_classperms_set *orig, struct cil_classperms_set **new) +{ + cil_classperms_set_init(new); + (*new)->set_str = orig->set_str; +} + +void cil_copy_classperms_list(struct cil_list *orig, struct cil_list **new) +{ + struct cil_list_item *orig_item; + + if (orig == NULL) { + return; + } + + cil_list_init(new, CIL_LIST_ITEM); + cil_list_for_each(orig_item, orig) { + if (orig_item->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp; + cil_copy_classperms(orig_item->data, &cp); + cil_list_append(*new, CIL_CLASSPERMS, cp); + } else { + struct cil_classperms_set *cp_set; + cil_copy_classperms_set(orig_item->data, &cp_set); + cil_list_append(*new, CIL_CLASSPERMS_SET, cp_set); + } + } +} + +int cil_copy_classmapping(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_classmapping *orig = data; + struct cil_classmapping *new = NULL; + + cil_classmapping_init(&new); + + new->map_class_str = orig->map_class_str; + new->map_perm_str = orig->map_perm_str; + + cil_copy_classperms_list(orig->classperms, &new->classperms); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_class(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_class *orig = data; + struct cil_class *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_class: class cannot be redefined\n"); + return SEPOL_ERR; + } + + cil_class_init(&new); + + new->common = NULL; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_classorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_classorder *orig = data; + struct cil_classorder *new = NULL; + + cil_classorder_init(&new); + if (orig->class_list_str != NULL) { + cil_copy_list(orig->class_list_str, &new->class_list_str); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_classpermission(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_classpermission *orig = data; + struct cil_classpermission *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + if (key != NULL) { + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "classpermission cannot be redefined\n"); + return SEPOL_ERR; + } + } + + cil_classpermission_init(&new); + + cil_copy_classperms_list(orig->classperms, &new->classperms); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_classpermissionset(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_classpermissionset *orig = data; + struct cil_classpermissionset *new = NULL; + + cil_classpermissionset_init(&new); + + new->set_str = orig->set_str; + + cil_copy_classperms_list(orig->classperms, &new->classperms); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_classcommon(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_classcommon *orig = data; + struct cil_classcommon *new = NULL; + + cil_classcommon_init(&new); + + new->class_str = orig->class_str; + new->common_str = orig->common_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_sid(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_sid *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_sid *new; + cil_sid_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_sidcontext *orig = data; + struct cil_sidcontext *new = NULL; + + cil_sidcontext_init(&new); + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_sidorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_sidorder *orig = data; + struct cil_sidorder *new = NULL; + + cil_sidorder_init(&new); + if (orig->sid_list_str != NULL) { + cil_copy_list(orig->sid_list_str, &new->sid_list_str); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_user(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_user *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_user *new; + cil_user_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +int cil_copy_userattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_userattribute *orig = data; + struct cil_userattribute *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + cil_userattribute_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_userattributeset *orig = data; + struct cil_userattributeset *new = NULL; + + cil_userattributeset_init(&new); + + new->attr_str = orig->attr_str; + + cil_copy_expr(db, orig->str_expr, &new->str_expr); + cil_copy_expr(db, orig->datum_expr, &new->datum_expr); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_userrole(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_userrole *orig = data; + struct cil_userrole *new = NULL; + + cil_userrole_init(&new); + + new->user_str = orig->user_str; + new->role_str = orig->role_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_userlevel(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_userlevel *orig = data; + struct cil_userlevel *new = NULL; + + cil_userlevel_init(&new); + + new->user_str = orig->user_str; + + if (orig->level_str != NULL) { + new->level_str = orig->level_str; + } else { + cil_copy_fill_level(db, orig->level, &new->level); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_userrange(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_userrange *orig = data; + struct cil_userrange *new = NULL; + + cil_userrange_init(&new); + + new->user_str = orig->user_str; + + if (orig->range_str != NULL) { + new->range_str = orig->range_str; + } else { + cil_levelrange_init(&new->range); + cil_copy_fill_levelrange(db, orig->range, new->range); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_userprefix(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_userprefix *orig = data; + struct cil_userprefix *new = NULL; + + cil_userprefix_init(&new); + + new->user_str = orig->user_str; + new->prefix_str = orig->prefix_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_role(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_role *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_role *new; + cil_role_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +int cil_copy_roletype(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_roletype *orig = data; + struct cil_roletype *new = NULL; + + cil_roletype_init(&new); + + new->role_str = orig->role_str; + new->type_str = orig->type_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_roleattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_roleattribute *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_roleattribute *new; + cil_roleattribute_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +int cil_copy_roleattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_roleattributeset *orig = data; + struct cil_roleattributeset *new = NULL; + + cil_roleattributeset_init(&new); + + new->attr_str = orig->attr_str; + + cil_copy_expr(db, orig->str_expr, &new->str_expr); + cil_copy_expr(db, orig->datum_expr, &new->datum_expr); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_roleallow(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_roleallow *orig = data; + struct cil_roleallow *new = NULL; + + cil_roleallow_init(&new); + + new->src_str = orig->src_str; + new->tgt_str = orig->tgt_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_type(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_type *new; + + cil_type_init(&new); + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_typepermissive(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_typepermissive *orig = data; + struct cil_typepermissive *new = NULL; + + cil_typepermissive_init(&new); + + new->type_str = orig->type_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_typeattribute(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_typeattribute *new; + + cil_typeattribute_init(&new); + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_typeattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_typeattributeset *orig = data; + struct cil_typeattributeset *new = NULL; + + cil_typeattributeset_init(&new); + + new->attr_str = orig->attr_str; + + cil_copy_expr(db, orig->str_expr, &new->str_expr); + cil_copy_expr(db, orig->datum_expr, &new->datum_expr); + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_expandtypeattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_expandtypeattribute *orig = data; + struct cil_expandtypeattribute *new = NULL; + + cil_expandtypeattribute_init(&new); + + if (orig->attr_strs != NULL) { + cil_copy_list(orig->attr_strs, &new->attr_strs); + } + + if (orig->attr_datums != NULL) { + cil_copy_list(orig->attr_datums, &new->attr_datums); + } + + new->expand = orig->expand; + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_alias(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_alias *orig = data; + struct cil_alias *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_alias: alias cannot be redefined\n"); + return SEPOL_ERR; + } + + cil_alias_init(&new); + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_aliasactual(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused))symtab_t *symtab) +{ + struct cil_aliasactual *orig = data; + struct cil_aliasactual *new = NULL; + + cil_aliasactual_init(&new); + + new->alias_str = orig->alias_str; + new->actual_str = orig->actual_str; + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_roletransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_roletransition *orig = data; + struct cil_roletransition *new = NULL; + + cil_roletransition_init(&new); + + new->src_str = orig->src_str; + new->tgt_str = orig->tgt_str; + new->obj_str = orig->obj_str; + new->result_str = orig->result_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_nametypetransition(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_nametypetransition *orig = data; + struct cil_nametypetransition *new = NULL; + + cil_nametypetransition_init(&new); + + new->src_str = orig->src_str; + new->tgt_str = orig->tgt_str; + new->obj_str = orig->obj_str; + new->name_str = orig->name_str; + new->result_str = orig->result_str; + + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_rangetransition(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_rangetransition *orig = data; + struct cil_rangetransition *new = NULL; + + cil_rangetransition_init(&new); + + new->src_str = orig->src_str; + new->exec_str = orig->exec_str; + new->obj_str = orig->obj_str; + + if (orig->range_str != NULL) { + new->range_str = orig->range_str; + } else { + cil_levelrange_init(&new->range); + cil_copy_fill_levelrange(db, orig->range, new->range); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_bool(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_bool *orig = data; + struct cil_bool *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_bool: boolean cannot be redefined\n"); + return SEPOL_ERR; + } + + cil_bool_init(&new); + new->value = orig->value; + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_tunable(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_tunable *orig = data; + struct cil_tunable *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_tunable: tunable cannot be redefined\n"); + return SEPOL_ERR; + } + + cil_tunable_init(&new); + new->value = orig->value; + *copy = new; + + return SEPOL_OK; +} + +static void cil_copy_fill_permissionx(struct cil_db *db, struct cil_permissionx *orig, struct cil_permissionx *new) +{ + new->kind = orig->kind; + new->obj_str = orig->obj_str; + cil_copy_expr(db, orig->expr_str, &new->expr_str); +} + +int cil_copy_avrule(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_avrule *orig = data; + struct cil_avrule *new = NULL; + + cil_avrule_init(&new); + + new->is_extended = orig->is_extended; + new->rule_kind = orig->rule_kind; + new->src_str = orig->src_str; + new->tgt_str = orig->tgt_str; + + if (!new->is_extended) { + cil_copy_classperms_list(orig->perms.classperms, &new->perms.classperms); + } else { + if (orig->perms.x.permx_str != NULL) { + new->perms.x.permx_str = orig->perms.x.permx_str; + } else { + cil_permissionx_init(&new->perms.x.permx); + cil_copy_fill_permissionx(db, orig->perms.x.permx, new->perms.x.permx); + } + } + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_permissionx(struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_permissionx *orig = data; + struct cil_permissionx *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_permissionx: permissionx cannot be redefined\n"); + return SEPOL_ERR; + } + + cil_permissionx_init(&new); + cil_copy_fill_permissionx(db, orig, new); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_type_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_type_rule *orig = data; + struct cil_type_rule *new = NULL; + + cil_type_rule_init(&new); + + new->rule_kind = orig->rule_kind; + new->src_str = orig->src_str; + new->tgt_str = orig->tgt_str; + new->obj_str = orig->obj_str; + new->result_str = orig->result_str; + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_sens(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_sens *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_sens *new; + cil_sens_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +int cil_copy_cat(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_cat *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_cat *new; + cil_cat_init(&new); + *copy = new; + } else { + *copy = datum; + } + + return SEPOL_OK; +} + +static void cil_copy_cats(struct cil_db *db, struct cil_cats *orig, struct cil_cats **new) +{ + cil_cats_init(new); + cil_copy_expr(db, orig->str_expr, &(*new)->str_expr); + cil_copy_expr(db, orig->datum_expr, &(*new)->datum_expr); +} + +int cil_copy_catset(struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_catset *orig = data; + struct cil_catset *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_catset: categoryset cannot be redefined\n"); + return SEPOL_ERR; + } + + cil_catset_init(&new); + + cil_copy_cats(db, orig->cats, &new->cats); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_senscat(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_senscat *orig = data; + struct cil_senscat *new = NULL; + + cil_senscat_init(&new); + + new->sens_str = orig->sens_str; + + cil_copy_cats(db, orig->cats, &new->cats); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_catorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_catorder *orig = data; + struct cil_catorder *new = NULL; + + cil_catorder_init(&new); + if (orig->cat_list_str != NULL) { + cil_copy_list(orig->cat_list_str, &new->cat_list_str); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_sensitivityorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_sensorder *orig = data; + struct cil_sensorder *new = NULL; + + cil_sensorder_init(&new); + if (orig->sens_list_str != NULL) { + cil_copy_list(orig->sens_list_str, &new->sens_list_str); + } + + *copy = new; + + return SEPOL_OK; +} + +void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new) +{ + cil_level_init(new); + + (*new)->sens_str = orig->sens_str; + + if (orig->cats != NULL) { + cil_copy_cats(db, orig->cats, &(*new)->cats); + } +} + +int cil_copy_level(struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_level *orig = data; + struct cil_level *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + if (key != NULL) { + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_level: level cannot be redefined\n"); + return SEPOL_ERR; + } + } + + cil_copy_fill_level(db, orig, &new); + + *copy = new; + + return SEPOL_OK; +} + +void cil_copy_fill_levelrange(struct cil_db *db, struct cil_levelrange *data, struct cil_levelrange *new) +{ + if (data->low_str != NULL) { + new->low_str = data->low_str; + } else { + cil_copy_fill_level(db, data->low, &new->low); + } + + if (data->high_str != NULL) { + new->high_str = data->high_str; + } else { + cil_copy_fill_level(db, data->high, &new->high); + } +} + +int cil_copy_levelrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_levelrange *orig = data; + struct cil_levelrange *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + if (key != NULL) { + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_levelrange: levelrange cannot be redefined\n"); + return SEPOL_ERR; + } + } + + cil_levelrange_init(&new); + cil_copy_fill_levelrange(db, orig, new); + + *copy = new; + + return SEPOL_OK; +} + +void cil_copy_fill_context(struct cil_db *db, struct cil_context *data, struct cil_context *new) +{ + new->user_str = data->user_str; + new->role_str = data->role_str; + new->type_str = data->type_str; + + if (data->range_str != NULL) { + new->range_str = data->range_str; + } else { + cil_levelrange_init(&new->range); + cil_copy_fill_levelrange(db, data->range, new->range); + } +} + +int cil_copy_context(struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_context *orig = data; + struct cil_context *new = NULL; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + if (key != NULL) { + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_context: context cannot be redefined\n"); + return SEPOL_ERR; + } + } + + cil_context_init(&new); + cil_copy_fill_context(db, orig, new); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_netifcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_netifcon *orig = data; + struct cil_netifcon *new = NULL; + + cil_netifcon_init(&new); + + new->interface_str = orig->interface_str; + + if (orig->if_context_str != NULL) { + new->if_context_str = orig->if_context_str; + } else { + cil_context_init(&new->if_context); + cil_copy_fill_context(db, orig->if_context, new->if_context); + } + + if (orig->packet_context_str != NULL) { + new->packet_context_str = orig->packet_context_str; + } else { + cil_context_init(&new->packet_context); + cil_copy_fill_context(db, orig->packet_context, new->packet_context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_genfscon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_genfscon *orig = data; + struct cil_genfscon *new = NULL; + + cil_genfscon_init(&new); + + new->fs_str = orig->fs_str; + new->path_str = orig->path_str; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_filecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_filecon *orig = data; + struct cil_filecon *new = NULL; + + cil_filecon_init(&new); + + new->path_str = orig->path_str; + new->type = orig->type; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else if (orig->context != NULL) { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_nodecon *orig = data; + struct cil_nodecon *new = NULL; + + cil_nodecon_init(&new); + + if (orig->addr_str != NULL) { + new->addr_str = orig->addr_str; + } else { + cil_ipaddr_init(&new->addr); + cil_copy_fill_ipaddr(orig->addr, new->addr); + } + + if (orig->mask_str != NULL) { + new->mask_str = orig->mask_str; + } else { + cil_ipaddr_init(&new->mask); + cil_copy_fill_ipaddr(orig->mask, new->mask); + } + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_ibpkeycon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_ibpkeycon *orig = data; + struct cil_ibpkeycon *new = NULL; + + cil_ibpkeycon_init(&new); + + new->subnet_prefix_str = orig->subnet_prefix_str; + new->pkey_low = orig->pkey_low; + new->pkey_high = orig->pkey_high; + + if (orig->context_str) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_ibendportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_ibendportcon *orig = data; + struct cil_ibendportcon *new = NULL; + + cil_ibendportcon_init(&new); + + new->dev_name_str = orig->dev_name_str; + new->port = orig->port; + + if (orig->context_str) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_portcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_portcon *orig = data; + struct cil_portcon *new = NULL; + + cil_portcon_init(&new); + + new->proto = orig->proto; + new->port_low = orig->port_low; + new->port_high = orig->port_high; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_pirqcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_pirqcon *orig = data; + struct cil_pirqcon *new = NULL; + + cil_pirqcon_init(&new); + + new->pirq = orig->pirq; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_iomemcon *orig = data; + struct cil_iomemcon *new = NULL; + + cil_iomemcon_init(&new); + + new->iomem_low = orig->iomem_low; + new->iomem_high = orig->iomem_high; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_ioportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_ioportcon *orig = data; + struct cil_ioportcon *new = NULL; + + cil_ioportcon_init(&new); + + new->ioport_low = orig->ioport_low; + new->ioport_high = orig->ioport_high; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_pcidevicecon *orig = data; + struct cil_pcidevicecon *new = NULL; + + cil_pcidevicecon_init(&new); + + new->dev = orig->dev; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_devicetreecon *orig = data; + struct cil_devicetreecon *new = NULL; + + cil_devicetreecon_init(&new); + + new->path = orig->path; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_fsuse *orig = data; + struct cil_fsuse *new = NULL; + + cil_fsuse_init(&new); + + new->type = orig->type; + new->fs_str = orig->fs_str; + + if (orig->context_str != NULL) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new) +{ + struct cil_list_item *curr; + + if (orig == NULL) { + *new = NULL; + return SEPOL_OK; + } + + cil_list_init(new, orig->flavor); + + cil_list_for_each(curr, orig) { + switch (curr->flavor) { + case CIL_LIST: { + struct cil_list *sub_list; + cil_copy_expr(db, curr->data, &sub_list); + cil_list_append(*new, CIL_LIST, sub_list); + break; + } + case CIL_STRING: + cil_list_append(*new, CIL_STRING, curr->data); + break; + case CIL_DATUM: + cil_list_append(*new, curr->flavor, curr->data); + break; + case CIL_OP: + cil_list_append(*new, curr->flavor, curr->data); + break; + case CIL_CONS_OPERAND: + cil_list_append(*new, curr->flavor, curr->data); + break; + default: + cil_log(CIL_INFO, "Unknown flavor %d in expression being copied\n",curr->flavor); + cil_list_append(*new, curr->flavor, curr->data); + break; + } + } + + return SEPOL_OK; +} + +int cil_copy_constrain(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_constrain *orig = data; + struct cil_constrain *new = NULL; + + cil_constrain_init(&new); + cil_copy_classperms_list(orig->classperms, &new->classperms); + + cil_copy_expr(db, orig->str_expr, &new->str_expr); + cil_copy_expr(db, orig->datum_expr, &new->datum_expr); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_validatetrans(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_validatetrans *orig = data; + struct cil_validatetrans *new = NULL; + + cil_validatetrans_init(&new); + + new->class_str = orig->class_str; + + cil_copy_expr(db, orig->str_expr, &new->str_expr); + cil_copy_expr(db, orig->datum_expr, &new->datum_expr); + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_call(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_call *orig = data; + struct cil_call *new = NULL; + int rc = SEPOL_ERR; + + cil_call_init(&new); + + new->macro_str = orig->macro_str; + new->macro = orig->macro; + + if (orig->args_tree != NULL) { + cil_tree_init(&new->args_tree); + rc = cil_copy_ast(db, orig->args_tree->root, new->args_tree->root); + if (rc != SEPOL_OK) { + goto exit; + } + } + + new->copied = orig->copied; + + *copy = new; + + return SEPOL_OK; + +exit: + cil_destroy_call(new); + return rc; +} + +static int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_macro *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + if (FLAVOR(datum) != CIL_MACRO) { + cil_tree_log(NODE(orig), CIL_ERR, "Macro %s being copied", key); + cil_tree_log(NODE(datum), CIL_ERR, " Conflicts with %s already declared", cil_node_to_string(NODE(datum))); + return SEPOL_ERR; + } + cil_tree_log(NODE(orig), CIL_WARN, "Skipping macro %s", key); + cil_tree_log(NODE(datum), CIL_WARN, " Previously declared"); + *copy = NULL; + } else { + struct cil_macro *new; + cil_macro_init(&new); + if (orig->params != NULL) { + cil_copy_list(orig->params, &new->params); + } + *copy = new; + } + + return SEPOL_OK; +} + +int cil_copy_optional(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_optional *new; + + cil_optional_init(&new); + *copy = new; + + return SEPOL_OK; +} + +void cil_copy_fill_ipaddr(struct cil_ipaddr *data, struct cil_ipaddr *new) +{ + new->family = data->family; + memcpy(&new->ip, &data->ip, sizeof(data->ip)); +} + +int cil_copy_ipaddr(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) +{ + struct cil_ipaddr *orig = data; + struct cil_ipaddr *new = NULL; + char * key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + cil_log(CIL_INFO, "cil_copy_ipaddr: ipaddress cannot be redefined\n"); + return SEPOL_ERR; + } + + cil_ipaddr_init(&new); + cil_copy_fill_ipaddr(orig, new); + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_condblock(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_condblock *orig = data; + struct cil_condblock *new = *copy; + cil_condblock_init(&new); + new->flavor = orig->flavor; + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_boolif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_booleanif *orig = data; + struct cil_booleanif *new = NULL; + + cil_boolif_init(&new); + + cil_copy_expr(db, orig->str_expr, &new->str_expr); + cil_copy_expr(db, orig->datum_expr, &new->datum_expr); + new->preserved_tunable = orig->preserved_tunable; + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_tunif(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_tunableif *orig = data; + struct cil_tunableif *new = NULL; + + cil_tunif_init(&new); + + cil_copy_expr(db, orig->str_expr, &new->str_expr); + cil_copy_expr(db, orig->datum_expr, &new->datum_expr); + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_default(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_default *orig = data; + struct cil_default *new = NULL; + + cil_default_init(&new); + + new->flavor = orig->flavor; + + if (orig->class_strs != NULL) { + cil_copy_list(orig->class_strs, &new->class_strs); + } + + new->object = orig->object; + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_defaultrange(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_defaultrange *orig = data; + struct cil_defaultrange *new = NULL; + + cil_defaultrange_init(&new); + + if (orig->class_strs != NULL) { + cil_copy_list(orig->class_strs, &new->class_strs); + } + + new->object_range = orig->object_range; + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_handleunknown(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_handleunknown *orig = data; + struct cil_handleunknown *new = NULL; + + cil_handleunknown_init(&new); + new->handle_unknown = orig->handle_unknown; + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_mls(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_mls *orig = data; + struct cil_mls *new = NULL; + + cil_mls_init(&new); + new->value = orig->value; + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_bounds *orig = data; + struct cil_bounds *new = NULL; + + cil_bounds_init(&new); + + new->parent_str = orig->parent_str; + new->child_str = orig->child_str; + + *copy = new; + + return SEPOL_OK; +} + +static int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_src_info *orig = data; + struct cil_src_info *new = NULL; + + cil_src_info_init(&new); + + new->kind = orig->kind; + new->hll_line = orig->hll_line; + new->path = orig->path; + + *copy = new; + + return SEPOL_OK; +} + +static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *parent = NULL; + struct cil_tree_node *new = NULL; + struct cil_db *db = NULL; + struct cil_args_copy *args = NULL; + struct cil_tree_node *namespace = NULL; + enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; + symtab_t *symtab = NULL; + void *data = NULL; + int (*copy_func)(struct cil_db *db, void *data, void **copy, symtab_t *symtab) = NULL; + struct cil_blockinherit *blockinherit = NULL; + + if (orig == NULL || extra_args == NULL) { + goto exit; + } + + args = extra_args; + parent = args->dest; + db = args->db; + + + switch (orig->flavor) { + case CIL_BLOCK: + copy_func = &cil_copy_block; + break; + case CIL_BLOCKABSTRACT: + if (args->orig_dest->flavor == CIL_BLOCKINHERIT) { + /* When inheriting a block, don't copy any blockabstract + * statements. Inheriting a block from a block that was + * just inherited never worked. */ + return SEPOL_OK; + } + copy_func = &cil_copy_blockabstract; + break; + case CIL_BLOCKINHERIT: + copy_func = &cil_copy_blockinherit; + break; + case CIL_POLICYCAP: + copy_func = &cil_copy_policycap; + break; + case CIL_PERM: + case CIL_MAP_PERM: + copy_func = &cil_copy_perm; + break; + case CIL_CLASSMAPPING: + copy_func = &cil_copy_classmapping; + break; + case CIL_CLASS: + case CIL_COMMON: + case CIL_MAP_CLASS: + copy_func = &cil_copy_class; + break; + case CIL_CLASSORDER: + copy_func = &cil_copy_classorder; + break; + case CIL_CLASSPERMISSION: + copy_func = &cil_copy_classpermission; + break; + case CIL_CLASSPERMISSIONSET: + copy_func = &cil_copy_classpermissionset; + break; + case CIL_CLASSCOMMON: + copy_func = &cil_copy_classcommon; + break; + case CIL_SID: + copy_func = &cil_copy_sid; + break; + case CIL_SIDCONTEXT: + copy_func = &cil_copy_sidcontext; + break; + case CIL_SIDORDER: + copy_func = &cil_copy_sidorder; + break; + case CIL_USER: + copy_func = &cil_copy_user; + break; + case CIL_USERATTRIBUTE: + copy_func = &cil_copy_userattribute; + break; + case CIL_USERATTRIBUTESET: + copy_func = &cil_copy_userattributeset; + break; + case CIL_USERROLE: + copy_func = &cil_copy_userrole; + break; + case CIL_USERLEVEL: + copy_func = &cil_copy_userlevel; + break; + case CIL_USERRANGE: + copy_func = &cil_copy_userrange; + break; + case CIL_USERBOUNDS: + copy_func = &cil_copy_bounds; + break; + case CIL_USERPREFIX: + copy_func = &cil_copy_userprefix; + break; + case CIL_ROLE: + copy_func = &cil_copy_role; + break; + case CIL_ROLETYPE: + copy_func = &cil_copy_roletype; + break; + case CIL_ROLEBOUNDS: + copy_func = &cil_copy_bounds; + break; + case CIL_ROLEATTRIBUTE: + copy_func = &cil_copy_roleattribute; + break; + case CIL_ROLEATTRIBUTESET: + copy_func = &cil_copy_roleattributeset; + break; + case CIL_ROLEALLOW: + copy_func = &cil_copy_roleallow; + break; + case CIL_TYPE: + copy_func = &cil_copy_type; + break; + case CIL_TYPEBOUNDS: + copy_func = &cil_copy_bounds; + break; + case CIL_TYPEPERMISSIVE: + copy_func = cil_copy_typepermissive; + break; + case CIL_TYPEATTRIBUTE: + copy_func = &cil_copy_typeattribute; + break; + case CIL_TYPEATTRIBUTESET: + copy_func = &cil_copy_typeattributeset; + break; + case CIL_EXPANDTYPEATTRIBUTE: + copy_func = &cil_copy_expandtypeattribute; + break; + case CIL_TYPEALIAS: + copy_func = &cil_copy_alias; + break; + case CIL_TYPEALIASACTUAL: + copy_func = &cil_copy_aliasactual; + break; + case CIL_ROLETRANSITION: + copy_func = &cil_copy_roletransition; + break; + case CIL_NAMETYPETRANSITION: + copy_func = &cil_copy_nametypetransition; + break; + case CIL_RANGETRANSITION: + copy_func = &cil_copy_rangetransition; + break; + case CIL_TUNABLE: + copy_func = &cil_copy_tunable; + break; + case CIL_BOOL: + copy_func = &cil_copy_bool; + break; + case CIL_AVRULE: + case CIL_AVRULEX: + copy_func = &cil_copy_avrule; + break; + case CIL_PERMISSIONX: + copy_func = &cil_copy_permissionx; + break; + case CIL_TYPE_RULE: + copy_func = &cil_copy_type_rule; + break; + case CIL_SENS: + copy_func = &cil_copy_sens; + break; + case CIL_SENSALIAS: + copy_func = &cil_copy_alias; + break; + case CIL_SENSALIASACTUAL: + copy_func = &cil_copy_aliasactual; + break; + case CIL_CAT: + copy_func = &cil_copy_cat; + break; + case CIL_CATALIAS: + copy_func = &cil_copy_alias; + break; + case CIL_CATALIASACTUAL: + copy_func = &cil_copy_aliasactual; + break; + case CIL_CATSET: + copy_func = &cil_copy_catset; + break; + case CIL_SENSCAT: + copy_func = &cil_copy_senscat; + break; + case CIL_CATORDER: + copy_func = &cil_copy_catorder; + break; + case CIL_SENSITIVITYORDER: + copy_func = &cil_copy_sensitivityorder; + break; + case CIL_LEVEL: + copy_func = &cil_copy_level; + break; + case CIL_LEVELRANGE: + copy_func = &cil_copy_levelrange; + break; + case CIL_CONTEXT: + copy_func = &cil_copy_context; + break; + case CIL_NETIFCON: + copy_func = &cil_copy_netifcon; + break; + case CIL_GENFSCON: + copy_func = &cil_copy_genfscon; + break; + case CIL_FILECON: + copy_func = &cil_copy_filecon; + break; + case CIL_NODECON: + copy_func = &cil_copy_nodecon; + break; + case CIL_IBPKEYCON: + copy_func = &cil_copy_ibpkeycon; + break; + case CIL_IBENDPORTCON: + copy_func = &cil_copy_ibendportcon; + break; + case CIL_PORTCON: + copy_func = &cil_copy_portcon; + break; + case CIL_PIRQCON: + copy_func = &cil_copy_pirqcon; + break; + case CIL_IOMEMCON: + copy_func = &cil_copy_iomemcon; + break; + case CIL_IOPORTCON: + copy_func = &cil_copy_ioportcon; + break; + case CIL_PCIDEVICECON: + copy_func = &cil_copy_pcidevicecon; + break; + case CIL_DEVICETREECON: + copy_func = &cil_copy_devicetreecon; + break; + case CIL_FSUSE: + copy_func = &cil_copy_fsuse; + break; + case CIL_CONSTRAIN: + case CIL_MLSCONSTRAIN: + copy_func = &cil_copy_constrain; + break; + case CIL_VALIDATETRANS: + case CIL_MLSVALIDATETRANS: + copy_func = &cil_copy_validatetrans; + break; + case CIL_CALL: + copy_func = &cil_copy_call; + break; + case CIL_MACRO: + copy_func = &cil_copy_macro; + break; + case CIL_NODE: + copy_func = &cil_copy_node; + break; + case CIL_OPTIONAL: + copy_func = &cil_copy_optional; + break; + case CIL_IPADDR: + copy_func = &cil_copy_ipaddr; + break; + case CIL_CONDBLOCK: + copy_func = &cil_copy_condblock; + break; + case CIL_BOOLEANIF: + copy_func = &cil_copy_boolif; + break; + case CIL_TUNABLEIF: + copy_func = &cil_copy_tunif; + break; + case CIL_DEFAULTUSER: + case CIL_DEFAULTROLE: + case CIL_DEFAULTTYPE: + copy_func = &cil_copy_default; + break; + case CIL_DEFAULTRANGE: + copy_func = &cil_copy_defaultrange; + break; + case CIL_HANDLEUNKNOWN: + copy_func = &cil_copy_handleunknown; + break; + case CIL_MLS: + copy_func = &cil_copy_mls; + break; + case CIL_SRC_INFO: + copy_func = &cil_copy_src_info; + break; + default: + goto exit; + } + + if (orig->flavor >= CIL_MIN_DECLARATIVE) { + rc = cil_flavor_to_symtab_index(orig->flavor, &sym_index); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_get_symtab(parent, &symtab, sym_index); + if (rc != SEPOL_OK) { + goto exit; + } + } + + rc = (*copy_func)(db, orig->data, &data, symtab); + if (rc == SEPOL_OK) { + if (orig->flavor == CIL_MACRO && data == NULL) { + /* Skipping macro re-declaration */ + if (args->orig_dest->flavor != CIL_BLOCKINHERIT) { + cil_log(CIL_ERR, " Re-declaration of macro is only allowed when inheriting a block\n"); + return SEPOL_ERR; + } + *finished = CIL_TREE_SKIP_HEAD; + return SEPOL_OK; + } + + cil_tree_node_init(&new); + + new->parent = parent; + new->line = orig->line; + new->hll_offset = orig->hll_offset; + new->flavor = orig->flavor; + new->data = data; + + if (orig->flavor == CIL_BLOCK && DATUM(data)->nodes->head != NULL) { + /* Duplicate block */ + if (args->orig_dest->flavor != CIL_BLOCKINHERIT) { + cil_log(CIL_ERR, " Re-declaration of block is only allowed when inheriting a block\n"); + rc = SEPOL_ERR; + goto exit; + } + cil_list_append(DATUM(new->data)->nodes, CIL_NODE, new); + } else if (orig->flavor >= CIL_MIN_DECLARATIVE) { + /* Check the flavor of data if was found in the destination symtab */ + if (DATUM(data)->nodes->head && FLAVOR(data) != orig->flavor) { + cil_tree_log(orig, CIL_ERR, "Incompatible flavor when trying to copy %s", DATUM(data)->name); + cil_tree_log(NODE(data), CIL_ERR, "Note: conflicting declaration"); + new->flavor = FLAVOR(data); + rc = SEPOL_ERR; + goto exit; + } + + rc = cil_add_decl_to_symtab(db, symtab, DATUM(orig->data)->name, DATUM(data), new); + if (rc != SEPOL_OK) { + if (rc == SEPOL_EEXIST) { + cil_symtab_datum_destroy(data); + free(data); + data = NULL; + rc = SEPOL_OK; + } else { + goto exit; + } + } + + namespace = new; + while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) { + namespace = namespace->parent; + } + + if (namespace->flavor == CIL_MACRO) { + rc = cil_verify_decl_does_not_shadow_macro_parameter(namespace->data, orig, DATUM(orig->data)->name); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + if (new->flavor == CIL_BLOCKINHERIT) { + blockinherit = new->data; + // if a blockinherit statement is copied before blockinherit are + // resolved (like in an in-statement), the block will not have been + // resolved yet, so there's nothing to append yet. This is fine, + // the copied blockinherit statement will be handled later, as if + // it wasn't in an in-statement + if (blockinherit->block != NULL) { + cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new); + } + } + + if (parent->cl_head == NULL) { + parent->cl_head = new; + parent->cl_tail = new; + } else { + parent->cl_tail->next = new; + parent->cl_tail = new; + } + + if (orig->cl_head != NULL) { + args->dest = new; + } + } else { + cil_tree_log(orig, CIL_ERR, "Problem copying %s node", cil_node_to_string(orig)); + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_node_destroy(&new); + return rc; +} + +static int __cil_copy_last_child_helper(__attribute__((unused)) struct cil_tree_node *orig, void *extra_args) +{ + struct cil_tree_node *node = NULL; + struct cil_args_copy *args = NULL; + + args = extra_args; + node = args->dest; + + if (node->flavor != CIL_ROOT) { + args->dest = node->parent; + } + + return SEPOL_OK; +} + +// dest is the parent node to copy into +// if the copy is for a call to a macro, dest should be a pointer to the call +int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_node *dest) +{ + int rc = SEPOL_ERR; + struct cil_args_copy extra_args; + + extra_args.orig_dest = dest; + extra_args.dest = dest; + extra_args.db = db; + + rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL, __cil_copy_last_child_helper, &extra_args); + if (rc != SEPOL_OK) { + cil_tree_log(dest, CIL_ERR, "Failed to copy %s to %s", cil_node_to_string(orig), cil_node_to_string(dest)); + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + diff --git a/kernel/libsepol/cil/src/cil_copy_ast.h b/kernel/libsepol/cil/src/cil_copy_ast.h new file mode 100644 index 00000000..a50c3708 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_copy_ast.h @@ -0,0 +1,120 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_COPY_H_ +#define CIL_COPY_H_ + +#include "cil_internal.h" +#include "cil_tree.h" +#include "cil_symtab.h" + +void cil_copy_list(struct cil_list *orig, struct cil_list **copy); +int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new); + +int cil_copy_block(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_blockabstract(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_blockinherit(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_perm(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_class(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_classorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_classmapping(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_permset(struct cil_db *db, void *data, void **copy, symtab_t *symtab); + +void cil_copy_classperms(struct cil_classperms *orig, struct cil_classperms **new); +void cil_copy_classperms_set(struct cil_classperms_set *orig, struct cil_classperms_set **new); +void cil_copy_classperms_list(struct cil_list *orig, struct cil_list **new); +int cil_copy_classpermission(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_classpermissionset(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab); +int cil_copy_common(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_classcommon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_sid(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_sidorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_user(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_userattribute(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_userrole(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_userlevel(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_userrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_userbounds(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_userprefix(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_role(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_roletype(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_rolebounds(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_roleattribute(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_roleattributeset(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_roleallow(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_type(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_typebounds(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_typepermissive(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_typeattribute(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_typeattributeset(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_typealias(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_nametypetransition(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_rangetransition(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_bool(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_avrule(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_type_rule(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_sens(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_sensalias(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_cat(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_catalias(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_catset(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_senscat(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_catorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_sensitivityorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new); +int cil_copy_level(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +void cil_copy_fill_levelrange(struct cil_db *db, struct cil_levelrange *orig, struct cil_levelrange *new); +int cil_copy_levelrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +void cil_copy_fill_context(struct cil_db *db, struct cil_context *orig, struct cil_context *new); +int cil_copy_context(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_netifcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_genfscon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_filecon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_ibpkeycon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_portcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_pirqcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_ioportcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_exrp(struct cil_db *db, struct cil_list *orig, struct cil_list **new); +int cil_copy_constrain(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_validatetrans(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_call(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_optional(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +void cil_copy_fill_ipaddr(struct cil_ipaddr *orig, struct cil_ipaddr *new); +int cil_copy_ipaddr(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_boolif(struct cil_db *db, void *data, void **copy, symtab_t *symtab); + +int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_node *dest); + +#endif diff --git a/kernel/libsepol/cil/src/cil_find.c b/kernel/libsepol/cil/src/cil_find.c new file mode 100644 index 00000000..ebfd6b9a --- /dev/null +++ b/kernel/libsepol/cil/src/cil_find.c @@ -0,0 +1,391 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "cil_internal.h" +#include "cil_find.h" +#include "cil_flavor.h" +#include "cil_list.h" +#include "cil_log.h" +#include "cil_symtab.h" + +struct cil_args_find { + enum cil_flavor flavor; + void *target; + struct cil_list *matching; + int match_self; +}; + +static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_datum *d2) +{ + enum cil_flavor f1 = FLAVOR(d1); + enum cil_flavor f2 = FLAVOR(d2); + + if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { + struct cil_type *t1 = (struct cil_type *)d1; + struct cil_type *t2 = (struct cil_type *)d2; + if (t1->value == t2->value) { + return CIL_TRUE; + } + } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *a = (struct cil_typeattribute *)d1; + struct cil_type *t = (struct cil_type *)d2; + if (ksu_ebitmap_get_bit(a->types, t->value)) { + return CIL_TRUE; + } + } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { + struct cil_type *t = (struct cil_type *)d1; + struct cil_typeattribute *a = (struct cil_typeattribute *)d2; + if (ksu_ebitmap_get_bit(a->types, t->value)) { + return CIL_TRUE; + } + } else { + /* Both are attributes */ + struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1; + struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2; + if (d1 == d2) { + return CIL_TRUE; + } else if (ebitmap_match_any(a1->types, a2->types)) { + return CIL_TRUE; + } + } + return CIL_FALSE; +} + +static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2) +{ + int rc = SEPOL_OK; + enum cil_flavor f1 = FLAVOR(d1); + enum cil_flavor f2 = FLAVOR(d2); + + if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { + struct cil_type *t1 = (struct cil_type *)d1; + struct cil_type *t2 = (struct cil_type *)d2; + if (t1->value == t2->value) { + ksu_ebitmap_set_bit(matches, t1->value, 1); + } + } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *a = (struct cil_typeattribute *)d1; + struct cil_type *t = (struct cil_type *)d2; + if (ksu_ebitmap_get_bit(a->types, t->value)) { + ksu_ebitmap_set_bit(matches, t->value, 1); + } + } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { + struct cil_type *t = (struct cil_type *)d1; + struct cil_typeattribute *a = (struct cil_typeattribute *)d2; + if (ksu_ebitmap_get_bit(a->types, t->value)) { + ksu_ebitmap_set_bit(matches, t->value, 1); + } + } else { + /* Both are attributes */ + struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1; + struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2; + rc = ksu_ebitmap_and(matches, a1->types, a2->types); + } + + return rc; +} + +/* s1 is the src type that is matched with a self + * s2, and t2 are the source and type of the other rule + */ +static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2) +{ + int rc; + struct cil_tree_node *n1 = NODE(s1); + if (n1->flavor != CIL_TYPEATTRIBUTE) { + rc = cil_type_match_any(s1, t2); + } else { + struct cil_typeattribute *a = (struct cil_typeattribute *)s1; + ebitmap_t map; + ebitmap_init(&map); + rc = cil_type_matches(&map, s2, t2); + if (rc < 0) { + ksu_ebitmap_destroy(&map); + goto exit; + } + if (map.node == NULL) { + rc = CIL_FALSE; + goto exit; + } + rc = ebitmap_match_any(&map, a->types); + ksu_ebitmap_destroy(&map); + } + +exit: + return rc; +} + +static int cil_classperms_match_any(struct cil_classperms *cp1, struct cil_classperms *cp2) +{ + struct cil_class *c1 = cp1->class; + struct cil_class *c2 = cp2->class; + struct cil_list_item *i1, *i2; + + if (&c1->datum != &c2->datum) return CIL_FALSE; + + cil_list_for_each(i1, cp1->perms) { + struct cil_perm *p1 = i1->data; + cil_list_for_each(i2, cp2->perms) { + struct cil_perm *p2 = i2->data; + if (&p1->datum == &p2->datum) return CIL_TRUE; + } + } + return CIL_FALSE; +} + +static int __cil_classperms_list_match_any(struct cil_classperms *cp1, struct cil_list *cpl2) +{ + int rc; + struct cil_list_item *curr; + + cil_list_for_each(curr, cpl2) { + if (curr->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = curr->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + rc = cil_classperms_match_any(cp1, cp); + if (rc == CIL_TRUE) return CIL_TRUE; + } else { /* MAP */ + struct cil_list_item *i = NULL; + cil_list_for_each(i, cp->perms) { + struct cil_perm *cmp = i->data; + rc = __cil_classperms_list_match_any(cp1, cmp->classperms); + if (rc == CIL_TRUE) return CIL_TRUE; + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + rc = __cil_classperms_list_match_any(cp1, cp->classperms); + if (rc == CIL_TRUE) return CIL_TRUE; + } + } + return CIL_FALSE; +} + +static int cil_classperms_list_match_any(struct cil_list *cpl1, struct cil_list *cpl2) +{ + int rc; + struct cil_list_item *curr; + + cil_list_for_each(curr, cpl1) { + if (curr->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = curr->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + rc = __cil_classperms_list_match_any(cp, cpl2); + if (rc == CIL_TRUE) return CIL_TRUE; + } else { /* MAP */ + struct cil_list_item *i = NULL; + cil_list_for_each(i, cp->perms) { + struct cil_perm *cmp = i->data; + rc = cil_classperms_list_match_any(cmp->classperms, cpl2); + if (rc == CIL_TRUE) return CIL_TRUE; + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + rc = cil_classperms_list_match_any(cp->classperms, cpl2); + if (rc == CIL_TRUE) return CIL_TRUE; + } + } + return CIL_FALSE; +} + +static void __add_classes_from_classperms_list(struct cil_list *classperms, struct cil_list *class_list) +{ + struct cil_list_item *curr; + + cil_list_for_each(curr, classperms) { + if (curr->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = curr->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + cil_list_append(class_list, CIL_CLASS, cp->class); + } else { /* MAP */ + struct cil_list_item *i = NULL; + cil_list_for_each(i, cp->perms) { + struct cil_perm *cmp = i->data; + __add_classes_from_classperms_list(cmp->classperms, class_list); + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + __add_classes_from_classperms_list(cp->classperms, class_list); + } + } +} + +static int __add_classes_from_map_perms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct cil_list *class_list = args; + struct cil_perm *cmp = (struct cil_perm *)d; + + __add_classes_from_classperms_list(cmp->classperms, class_list); + + return SEPOL_OK; +} + +struct cil_list *cil_expand_class(struct cil_class *class) +{ + struct cil_list *class_list; + + cil_list_init(&class_list, CIL_CLASS); + + if (FLAVOR(class) == CIL_CLASS) { + cil_list_append(class_list, CIL_CLASS, class); + } else { /* MAP */ + cil_symtab_map(&class->perms, __add_classes_from_map_perms, class_list); + } + + return class_list; +} + +static int cil_permissionx_match_any(struct cil_permissionx *px1, struct cil_permissionx *px2) +{ + int rc = CIL_FALSE; + struct cil_list *cl1 = NULL; + struct cil_list *cl2 = NULL; + + if (px1->kind != px2->kind) goto exit; + + if (!ebitmap_match_any(px1->perms, px2->perms)) goto exit; + + cl1 = cil_expand_class(px1->obj); + cl2 = cil_expand_class(px2->obj); + + if (!cil_list_match_any(cl1, cl2)) goto exit; + + rc = CIL_TRUE; + +exit: + cil_list_destroy(&cl1, CIL_FALSE); + cil_list_destroy(&cl2, CIL_FALSE); + + return rc; +} + +static int cil_find_matching_avrule(struct cil_tree_node *node, struct cil_avrule *avrule, struct cil_avrule *target, struct cil_list *matching, int match_self) +{ + int rc = SEPOL_OK; + struct cil_symtab_datum *s1 = avrule->src; + struct cil_symtab_datum *t1 = avrule->tgt; + struct cil_symtab_datum *s2 = target->src; + struct cil_symtab_datum *t2 = target->tgt; + + if (match_self != CIL_TRUE && avrule == target) goto exit; + + if (avrule->rule_kind != target->rule_kind) goto exit; + + if (avrule->is_extended != target->is_extended) goto exit; + + if (!cil_type_match_any(s1, s2)) goto exit; + + if (t1->fqn != CIL_KEY_SELF && t2->fqn != CIL_KEY_SELF) { + if (!cil_type_match_any(t1, t2)) goto exit; + } else { + if (t1->fqn == CIL_KEY_SELF && t2->fqn == CIL_KEY_SELF) { + /* The earlier check whether s1 and s2 matches is all that is needed */ + } else if (t1->fqn == CIL_KEY_SELF) { + rc = cil_self_match_any(s1, s2, t2); + if (rc < 0) { + goto exit; + } else if (rc == CIL_FALSE) { + rc = SEPOL_OK; + goto exit; + } + } else if (t2->fqn == CIL_KEY_SELF) { + rc = cil_self_match_any(s2, s1, t1); + if (rc < 0) { + goto exit; + } else if (rc == CIL_FALSE) { + rc = SEPOL_OK; + goto exit; + } + } + } + + if (!target->is_extended) { + if (cil_classperms_list_match_any(avrule->perms.classperms, target->perms.classperms)) { + cil_list_append(matching, CIL_NODE, node); + } + } else { + if (cil_permissionx_match_any(avrule->perms.x.permx, target->perms.x.permx)) { + cil_list_append(matching, CIL_NODE, node); + } + } + + rc = SEPOL_OK; + +exit: + return rc; +} + +static int __cil_find_matching_avrule_in_ast(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_OK; + struct cil_args_find *args = extra_args; + + if (node->flavor == CIL_BLOCK) { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + goto exit; + } + } else if (node->flavor == CIL_MACRO) { + *finished = CIL_TREE_SKIP_HEAD; + goto exit; + } else if (node->flavor == CIL_AVRULE || node->flavor == CIL_AVRULEX) { + if (node->flavor == args->flavor) { + rc = cil_find_matching_avrule(node, node->data, args->target, args->matching, args->match_self); + } + } + +exit: + return rc; +} + +int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self) +{ + int rc; + struct cil_args_find args; + + args.flavor = flavor; + args.target = target; + args.matching = matching; + args.match_self = match_self; + + rc = cil_tree_walk(current, __cil_find_matching_avrule_in_ast, NULL, NULL, &args); + if (rc) { + cil_log(CIL_ERR, "An error occurred while searching for avrule in AST\n"); + } + + return rc; +} diff --git a/kernel/libsepol/cil/src/cil_find.h b/kernel/libsepol/cil/src/cil_find.h new file mode 100644 index 00000000..463ef341 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_find.h @@ -0,0 +1,40 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include "cil_flavor.h" +#include "cil_tree.h" +#include "cil_list.h" + +#ifndef CIL_FIND_H_ +#define CIL_FIND_H_ + +int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self); +struct cil_list *cil_expand_class(struct cil_class *class); + +#endif diff --git a/kernel/libsepol/cil/src/cil_flavor.h b/kernel/libsepol/cil/src/cil_flavor.h new file mode 100644 index 00000000..c2f0cee7 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_flavor.h @@ -0,0 +1,194 @@ +/* + * Copyright 2013 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_FLAVOR_H_ +#define CIL_FLAVOR_H_ + +/* + Tree/list node types +*/ +#define CIL_MIN_OP_OPERANDS 1000 +#define CIL_MIN_DECLARATIVE 2000 + +enum cil_flavor { + CIL_NONE = 0, + CIL_ROOT, + CIL_NODE, + CIL_STRING, + CIL_DATUM, + CIL_LIST, + CIL_LIST_ITEM, + CIL_PARAM, + CIL_ARGS, + CIL_BLOCKINHERIT, + CIL_BLOCKABSTRACT, + CIL_IN, + CIL_CALL, + CIL_BOOLEANIF, + CIL_TUNABLEIF, + CIL_CONDBLOCK, + CIL_CONDTRUE, + CIL_CONDFALSE, + CIL_CLASSORDER, + CIL_CLASSCOMMON, + CIL_CLASSMAPPING, + CIL_CLASSPERMS, + CIL_CLASSPERMS_SET, + CIL_CLASSPERMISSIONSET, + CIL_USERPREFIX, + CIL_USERROLE, + CIL_USERATTRIBUTESET, + CIL_USERLEVEL, + CIL_USERRANGE, + CIL_USERBOUNDS, + CIL_SELINUXUSER, + CIL_SELINUXUSERDEFAULT, + CIL_ROLEATTRIBUTESET, + CIL_ROLETYPE, + CIL_ROLEBOUNDS, + CIL_TYPEATTRIBUTESET, + CIL_EXPANDTYPEATTRIBUTE, + CIL_TYPEALIASACTUAL, + CIL_TYPEBOUNDS, + CIL_TYPEPERMISSIVE, + CIL_SENSALIASACTUAL, + CIL_SENSITIVITYORDER, + CIL_SENSCAT, + CIL_CATALIASACTUAL, + CIL_CATORDER, + CIL_SIDORDER, + CIL_ROLEALLOW, + CIL_AVRULE, + CIL_AVRULEX, + CIL_ROLETRANSITION, + CIL_TYPE_RULE, + CIL_NAMETYPETRANSITION, + CIL_RANGETRANSITION, + CIL_CONSTRAIN, + CIL_MLSCONSTRAIN, + CIL_VALIDATETRANS, + CIL_MLSVALIDATETRANS, + CIL_SIDCONTEXT, + CIL_FSUSE, + CIL_FILECON, + CIL_PORTCON, + CIL_NODECON, + CIL_GENFSCON, + CIL_NETIFCON, + CIL_PIRQCON, + CIL_IOMEMCON, + CIL_IOPORTCON, + CIL_PCIDEVICECON, + CIL_DEVICETREECON, + CIL_DEFAULTUSER, + CIL_DEFAULTROLE, + CIL_DEFAULTTYPE, + CIL_DEFAULTRANGE, + CIL_HANDLEUNKNOWN, + CIL_MLS, + CIL_SRC_INFO, + CIL_IBPKEYCON, + CIL_IBENDPORTCON, + +/* + * boolean constraint set catset + * dom X + * domby X + * incomp X + * eq X X + * ne X X + * and X X X X + * not X X X X + * or X X X X + * xor X X X + * all X X + * range X +*/ + CIL_OP = CIL_MIN_OP_OPERANDS, + CIL_ALL, + CIL_AND, + CIL_OR, + CIL_XOR, + CIL_NOT, + CIL_EQ, + CIL_NEQ, + CIL_RANGE, + CIL_CONS_DOM, + CIL_CONS_DOMBY, + CIL_CONS_INCOMP, + CIL_CONS_OPERAND, + CIL_CONS_U1, + CIL_CONS_U2, + CIL_CONS_U3, + CIL_CONS_T1, + CIL_CONS_T2, + CIL_CONS_T3, + CIL_CONS_R1, + CIL_CONS_R2, + CIL_CONS_R3, + CIL_CONS_L1, + CIL_CONS_L2, + CIL_CONS_H1, + CIL_CONS_H2, + + CIL_BLOCK = CIL_MIN_DECLARATIVE, + CIL_MACRO, + CIL_OPTIONAL, + CIL_BOOL, + CIL_TUNABLE, + CIL_PERM, + CIL_MAP_PERM, + CIL_COMMON, + CIL_CLASS, + CIL_MAP_CLASS, + CIL_CLASSPERMISSION, + CIL_USER, + CIL_USERATTRIBUTE, + CIL_ROLE, + CIL_ROLEATTRIBUTE, + CIL_TYPE, + CIL_TYPEATTRIBUTE, + CIL_TYPEALIAS, + CIL_SENS, + CIL_SENSALIAS, + CIL_CAT, + CIL_CATSET, + CIL_CATALIAS, + CIL_LEVEL, + CIL_LEVELRANGE, + CIL_SID, + CIL_NAME, + CIL_CONTEXT, + CIL_IPADDR, + CIL_POLICYCAP, + CIL_PERMISSIONX +}; + + +#endif /* CIL_FLAVOR_H_ */ diff --git a/kernel/libsepol/cil/src/cil_fqn.c b/kernel/libsepol/cil/src/cil_fqn.c new file mode 100644 index 00000000..46db069b --- /dev/null +++ b/kernel/libsepol/cil/src/cil_fqn.c @@ -0,0 +1,143 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include + +#include "cil_fqn.h" +#include "cil_internal.h" +#include "cil_log.h" +#include "cil_strpool.h" +#include "cil_symtab.h" + +struct cil_fqn_args { + char prefix[CIL_MAX_NAME_LENGTH]; + int len; + struct cil_tree_node *node; +}; + +static int __cil_fqn_qualify_decls(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct cil_fqn_args *fqn_args = args; + struct cil_symtab_datum *datum = (struct cil_symtab_datum *)d; + int newlen; + char prefix[CIL_MAX_NAME_LENGTH]; + int rc = SEPOL_OK; + + if (fqn_args->len == 0) { + goto exit; + } + + newlen = fqn_args->len + strlen(datum->name); + if (newlen >= CIL_MAX_NAME_LENGTH) { + cil_log(CIL_INFO, "Fully qualified name for %s is too long\n", datum->name); + rc = SEPOL_ERR; + goto exit; + } + strcpy(prefix, fqn_args->prefix); + strcat(prefix, datum->name); + datum->fqn = cil_strpool_add(prefix); + +exit: + return rc; +} + +static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct cil_fqn_args *fqn_args = args; + struct cil_fqn_args child_args; + struct cil_block *block = (struct cil_block *)d; + struct cil_symtab_datum *datum = (struct cil_symtab_datum *)block; + struct cil_tree_node *node = NODE(datum); + int i; + int rc = SEPOL_OK; + int newlen; + + if (node->flavor != CIL_BLOCK) { + goto exit; + } + + newlen = fqn_args->len + strlen(datum->name) + 1; + if (newlen >= CIL_MAX_NAME_LENGTH) { + cil_log(CIL_INFO, "Fully qualified name for block %s is too long\n", datum->name); + rc = SEPOL_ERR; + goto exit; + } + + child_args.node = node; + child_args.len = newlen; + strcpy(child_args.prefix, fqn_args->prefix); + strcat(child_args.prefix, datum->name); + strcat(child_args.prefix, "."); + + for (i=1; isymtab[i]), __cil_fqn_qualify_decls, &child_args); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + } + + rc = cil_symtab_map(&(block->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &child_args); + +exit: + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_ERR,"Problem qualifying names in block"); + } + + return rc; +} + +int cil_fqn_qualify(struct cil_tree_node *root_node) +{ + struct cil_root *root = root_node->data; + struct cil_fqn_args fqn_args; + + fqn_args.prefix[0] = '\0'; + fqn_args.len = 0; + fqn_args.node = root_node; + + return cil_symtab_map(&(root->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &fqn_args); +} + diff --git a/kernel/libsepol/cil/src/cil_fqn.h b/kernel/libsepol/cil/src/cil_fqn.h new file mode 100644 index 00000000..9248ca18 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_fqn.h @@ -0,0 +1,38 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_FQN_H_ +#define CIL_FQN_H_ + +#include "cil_internal.h" +#include "cil_tree.h" + +int cil_fqn_qualify(struct cil_tree_node *root_node); + +#endif /* CIL_FQN_H_ */ diff --git a/kernel/libsepol/cil/src/cil_internal.h b/kernel/libsepol/cil/src/cil_internal.h new file mode 100644 index 00000000..a7604762 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_internal.h @@ -0,0 +1,1089 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_INTERNAL_H_ +#define CIL_INTERNAL_H_ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "cil_flavor.h" +#include "cil_tree.h" +#include "cil_symtab.h" +#include "cil_mem.h" + +#define CIL_MAX_NAME_LENGTH 2048 + +#define CIL_DEGENERATE_INHERITANCE_DEPTH 10UL +#define CIL_DEGENERATE_INHERITANCE_MINIMUM (0x01 << CIL_DEGENERATE_INHERITANCE_DEPTH) +#define CIL_DEGENERATE_INHERITANCE_GROWTH 10UL + +enum cil_pass { + CIL_PASS_INIT = 0, + + CIL_PASS_TIF, + CIL_PASS_IN_BEFORE, + CIL_PASS_BLKIN_LINK, + CIL_PASS_BLKIN_COPY, + CIL_PASS_BLKABS, + CIL_PASS_IN_AFTER, + CIL_PASS_CALL1, + CIL_PASS_CALL2, + CIL_PASS_ALIAS1, + CIL_PASS_ALIAS2, + CIL_PASS_MISC1, + CIL_PASS_MLS, + CIL_PASS_MISC2, + CIL_PASS_MISC3, + + CIL_PASS_NUM +}; + + +/* + Keywords +*/ +extern char *CIL_KEY_CONS_T1; +extern char *CIL_KEY_CONS_T2; +extern char *CIL_KEY_CONS_T3; +extern char *CIL_KEY_CONS_R1; +extern char *CIL_KEY_CONS_R2; +extern char *CIL_KEY_CONS_R3; +extern char *CIL_KEY_CONS_U1; +extern char *CIL_KEY_CONS_U2; +extern char *CIL_KEY_CONS_U3; +extern char *CIL_KEY_CONS_L1; +extern char *CIL_KEY_CONS_L2; +extern char *CIL_KEY_CONS_H1; +extern char *CIL_KEY_CONS_H2; +extern char *CIL_KEY_AND; +extern char *CIL_KEY_OR; +extern char *CIL_KEY_NOT; +extern char *CIL_KEY_EQ; +extern char *CIL_KEY_NEQ; +extern char *CIL_KEY_CONS_DOM; +extern char *CIL_KEY_CONS_DOMBY; +extern char *CIL_KEY_CONS_INCOMP; +extern char *CIL_KEY_CONDTRUE; +extern char *CIL_KEY_CONDFALSE; +extern char *CIL_KEY_SELF; +extern char *CIL_KEY_OBJECT_R; +extern char *CIL_KEY_STAR; +extern char *CIL_KEY_TCP; +extern char *CIL_KEY_UDP; +extern char *CIL_KEY_DCCP; +extern char *CIL_KEY_SCTP; +extern char *CIL_KEY_AUDITALLOW; +extern char *CIL_KEY_TUNABLEIF; +extern char *CIL_KEY_ALLOW; +extern char *CIL_KEY_DONTAUDIT; +extern char *CIL_KEY_TYPETRANSITION; +extern char *CIL_KEY_TYPECHANGE; +extern char *CIL_KEY_CALL; +extern char *CIL_KEY_TUNABLE; +extern char *CIL_KEY_XOR; +extern char *CIL_KEY_ALL; +extern char *CIL_KEY_RANGE; +extern char *CIL_KEY_GLOB; +extern char *CIL_KEY_FILE; +extern char *CIL_KEY_DIR; +extern char *CIL_KEY_CHAR; +extern char *CIL_KEY_BLOCK; +extern char *CIL_KEY_SOCKET; +extern char *CIL_KEY_PIPE; +extern char *CIL_KEY_SYMLINK; +extern char *CIL_KEY_ANY; +extern char *CIL_KEY_XATTR; +extern char *CIL_KEY_TASK; +extern char *CIL_KEY_TRANS; +extern char *CIL_KEY_TYPE; +extern char *CIL_KEY_ROLE; +extern char *CIL_KEY_USER; +extern char *CIL_KEY_USERATTRIBUTE; +extern char *CIL_KEY_USERATTRIBUTESET; +extern char *CIL_KEY_SENSITIVITY; +extern char *CIL_KEY_CATEGORY; +extern char *CIL_KEY_CATSET; +extern char *CIL_KEY_LEVEL; +extern char *CIL_KEY_LEVELRANGE; +extern char *CIL_KEY_CLASS; +extern char *CIL_KEY_IPADDR; +extern char *CIL_KEY_MAP_CLASS; +extern char *CIL_KEY_CLASSPERMISSION; +extern char *CIL_KEY_BOOL; +extern char *CIL_KEY_STRING; +extern char *CIL_KEY_NAME; +extern char *CIL_KEY_SOURCE; +extern char *CIL_KEY_TARGET; +extern char *CIL_KEY_LOW; +extern char *CIL_KEY_HIGH; +extern char *CIL_KEY_LOW_HIGH; +extern char *CIL_KEY_GLBLUB; +extern char *CIL_KEY_HANDLEUNKNOWN; +extern char *CIL_KEY_HANDLEUNKNOWN_ALLOW; +extern char *CIL_KEY_HANDLEUNKNOWN_DENY; +extern char *CIL_KEY_HANDLEUNKNOWN_REJECT; +extern char *CIL_KEY_MACRO; +extern char *CIL_KEY_IN; +extern char *CIL_KEY_IN_BEFORE; +extern char *CIL_KEY_IN_AFTER; +extern char *CIL_KEY_MLS; +extern char *CIL_KEY_DEFAULTRANGE; +extern char *CIL_KEY_BLOCKINHERIT; +extern char *CIL_KEY_BLOCKABSTRACT; +extern char *CIL_KEY_CLASSORDER; +extern char *CIL_KEY_CLASSMAPPING; +extern char *CIL_KEY_CLASSPERMISSIONSET; +extern char *CIL_KEY_COMMON; +extern char *CIL_KEY_CLASSCOMMON; +extern char *CIL_KEY_SID; +extern char *CIL_KEY_SIDCONTEXT; +extern char *CIL_KEY_SIDORDER; +extern char *CIL_KEY_USERLEVEL; +extern char *CIL_KEY_USERRANGE; +extern char *CIL_KEY_USERBOUNDS; +extern char *CIL_KEY_USERPREFIX; +extern char *CIL_KEY_SELINUXUSER; +extern char *CIL_KEY_SELINUXUSERDEFAULT; +extern char *CIL_KEY_TYPEATTRIBUTE; +extern char *CIL_KEY_TYPEATTRIBUTESET; +extern char *CIL_KEY_EXPANDTYPEATTRIBUTE; +extern char *CIL_KEY_TYPEALIAS; +extern char *CIL_KEY_TYPEALIASACTUAL; +extern char *CIL_KEY_TYPEBOUNDS; +extern char *CIL_KEY_TYPEPERMISSIVE; +extern char *CIL_KEY_RANGETRANSITION; +extern char *CIL_KEY_USERROLE; +extern char *CIL_KEY_ROLETYPE; +extern char *CIL_KEY_ROLETRANSITION; +extern char *CIL_KEY_ROLEALLOW; +extern char *CIL_KEY_ROLEATTRIBUTE; +extern char *CIL_KEY_ROLEATTRIBUTESET; +extern char *CIL_KEY_ROLEBOUNDS; +extern char *CIL_KEY_BOOLEANIF; +extern char *CIL_KEY_NEVERALLOW; +extern char *CIL_KEY_TYPEMEMBER; +extern char *CIL_KEY_SENSALIAS; +extern char *CIL_KEY_SENSALIASACTUAL; +extern char *CIL_KEY_CATALIAS; +extern char *CIL_KEY_CATALIASACTUAL; +extern char *CIL_KEY_CATORDER; +extern char *CIL_KEY_SENSITIVITYORDER; +extern char *CIL_KEY_SENSCAT; +extern char *CIL_KEY_CONSTRAIN; +extern char *CIL_KEY_MLSCONSTRAIN; +extern char *CIL_KEY_VALIDATETRANS; +extern char *CIL_KEY_MLSVALIDATETRANS; +extern char *CIL_KEY_CONTEXT; +extern char *CIL_KEY_FILECON; +extern char *CIL_KEY_IBPKEYCON; +extern char *CIL_KEY_IBENDPORTCON; +extern char *CIL_KEY_PORTCON; +extern char *CIL_KEY_NODECON; +extern char *CIL_KEY_GENFSCON; +extern char *CIL_KEY_NETIFCON; +extern char *CIL_KEY_PIRQCON; +extern char *CIL_KEY_IOMEMCON; +extern char *CIL_KEY_IOPORTCON; +extern char *CIL_KEY_PCIDEVICECON; +extern char *CIL_KEY_DEVICETREECON; +extern char *CIL_KEY_FSUSE; +extern char *CIL_KEY_POLICYCAP; +extern char *CIL_KEY_OPTIONAL; +extern char *CIL_KEY_DEFAULTUSER; +extern char *CIL_KEY_DEFAULTROLE; +extern char *CIL_KEY_DEFAULTTYPE; +extern char *CIL_KEY_ROOT; +extern char *CIL_KEY_NODE; +extern char *CIL_KEY_PERM; +extern char *CIL_KEY_ALLOWX; +extern char *CIL_KEY_AUDITALLOWX; +extern char *CIL_KEY_DONTAUDITX; +extern char *CIL_KEY_NEVERALLOWX; +extern char *CIL_KEY_PERMISSIONX; +extern char *CIL_KEY_IOCTL; +extern char *CIL_KEY_UNORDERED; +extern char *CIL_KEY_SRC_INFO; +extern char *CIL_KEY_SRC_CIL; +extern char *CIL_KEY_SRC_HLL_LMS; +extern char *CIL_KEY_SRC_HLL_LMX; +extern char *CIL_KEY_SRC_HLL_LME; + +/* + Symbol Table Array Indices +*/ +enum cil_sym_index { + CIL_SYM_BLOCKS = 0, + CIL_SYM_USERS, + CIL_SYM_ROLES, + CIL_SYM_TYPES, + CIL_SYM_COMMONS, + CIL_SYM_CLASSES, + CIL_SYM_CLASSPERMSETS, + CIL_SYM_BOOLS, + CIL_SYM_TUNABLES, + CIL_SYM_SENS, + CIL_SYM_CATS, + CIL_SYM_SIDS, + CIL_SYM_CONTEXTS, + CIL_SYM_LEVELS, + CIL_SYM_LEVELRANGES, + CIL_SYM_POLICYCAPS, + CIL_SYM_IPADDRS, + CIL_SYM_NAMES, + CIL_SYM_PERMX, + CIL_SYM_NUM, + CIL_SYM_UNKNOWN, + CIL_SYM_PERMS // Special case for permissions. This symtab is not included in arrays +}; + +enum cil_sym_array { + CIL_SYM_ARRAY_ROOT = 0, + CIL_SYM_ARRAY_BLOCK, + CIL_SYM_ARRAY_IN, + CIL_SYM_ARRAY_MACRO, + CIL_SYM_ARRAY_CONDBLOCK, + CIL_SYM_ARRAY_NUM +}; + +extern const int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM]; + +#define CIL_CLASS_SYM_SIZE 256 +#define CIL_PERMS_PER_CLASS (sizeof(sepol_access_vector_t) * 8) + +struct cil_db { + struct cil_tree *parse; + struct cil_tree *ast; + struct cil_type *selftype; + struct cil_list *sidorder; + struct cil_list *classorder; + struct cil_list *catorder; + struct cil_list *sensitivityorder; + struct cil_sort *netifcon; + struct cil_sort *genfscon; + struct cil_sort *filecon; + struct cil_sort *nodecon; + struct cil_sort *ibpkeycon; + struct cil_sort *ibendportcon; + struct cil_sort *portcon; + struct cil_sort *pirqcon; + struct cil_sort *iomemcon; + struct cil_sort *ioportcon; + struct cil_sort *pcidevicecon; + struct cil_sort *devicetreecon; + struct cil_sort *fsuse; + struct cil_list *userprefixes; + struct cil_list *selinuxusers; + struct cil_list *names; + int num_types_and_attrs; + int num_classes; + int num_cats; + int num_types; + int num_roles; + int num_users; + struct cil_type **val_to_type; + struct cil_role **val_to_role; + struct cil_user **val_to_user; + int disable_dontaudit; + int disable_neverallow; + int attrs_expand_generated; + unsigned attrs_expand_size; + int preserve_tunables; + int handle_unknown; + int mls; + int multiple_decls; + int qualified_names; + int target_platform; + int policy_version; +}; + +struct cil_root { + symtab_t symtab[CIL_SYM_NUM]; +}; + +struct cil_sort { + enum cil_flavor flavor; + uint32_t count; + uint32_t index; + void **array; +}; + +struct cil_block { + struct cil_symtab_datum datum; + symtab_t symtab[CIL_SYM_NUM]; + uint16_t is_abstract; + struct cil_list *bi_nodes; +}; + +struct cil_blockinherit { + char *block_str; + struct cil_block *block; +}; + +struct cil_blockabstract { + char *block_str; +}; + +struct cil_in { + symtab_t symtab[CIL_SYM_NUM]; + int is_after; + char *block_str; +}; + +struct cil_optional { + struct cil_symtab_datum datum; +}; + +struct cil_perm { + struct cil_symtab_datum datum; + unsigned int value; + struct cil_list *classperms; /* Only used for map perms */ +}; + +struct cil_class { + struct cil_symtab_datum datum; + symtab_t perms; + unsigned int num_perms; + struct cil_class *common; /* Only used for kernel class */ + uint32_t ordered; /* Only used for kernel class */ +}; + +struct cil_classorder { + struct cil_list *class_list_str; +}; + +struct cil_classperms_set { + char *set_str; + struct cil_classpermission *set; +}; + +struct cil_classperms { + char *class_str; + struct cil_class *class; + struct cil_list *perm_strs; + struct cil_list *perms; +}; + +struct cil_classpermission { + struct cil_symtab_datum datum; + struct cil_list *classperms; +}; + +struct cil_classpermissionset { + char *set_str; + struct cil_list *classperms; +}; + +struct cil_classmapping { + char *map_class_str; + char *map_perm_str; + struct cil_list *classperms; +}; + +struct cil_classcommon { + char *class_str; + char *common_str; +}; + +struct cil_alias { + struct cil_symtab_datum datum; + void *actual; +}; + +struct cil_aliasactual { + char *alias_str; + char *actual_str; +}; + +struct cil_sid { + struct cil_symtab_datum datum; + struct cil_context *context; + uint32_t ordered; +}; + +struct cil_sidcontext { + char *sid_str; + char *context_str; + struct cil_context *context; +}; + +struct cil_sidorder { + struct cil_list *sid_list_str; +}; + +struct cil_user { + struct cil_symtab_datum datum; + struct cil_user *bounds; + ebitmap_t *roles; + struct cil_level *dftlevel; + struct cil_levelrange *range; + int value; +}; + +struct cil_userattribute { + struct cil_symtab_datum datum; + struct cil_list *expr_list; + ebitmap_t *users; +}; + +struct cil_userattributeset { + char *attr_str; + struct cil_list *str_expr; + struct cil_list *datum_expr; +}; + +struct cil_userrole { + char *user_str; + void *user; + char *role_str; + void *role; +}; + +struct cil_userlevel { + char *user_str; + char *level_str; + struct cil_level *level; +}; + +struct cil_userrange { + char *user_str; + char *range_str; + struct cil_levelrange *range; +}; + +struct cil_userprefix { + char *user_str; + struct cil_user *user; + char *prefix_str; +}; + +struct cil_selinuxuser { + char *name_str; + char *user_str; + struct cil_user *user; + char *range_str; + struct cil_levelrange *range; +}; + +struct cil_role { + struct cil_symtab_datum datum; + struct cil_role *bounds; + ebitmap_t *types; + int value; +}; + +struct cil_roleattribute { + struct cil_symtab_datum datum; + struct cil_list *expr_list; + ebitmap_t *roles; +}; + +struct cil_roleattributeset { + char *attr_str; + struct cil_list *str_expr; + struct cil_list *datum_expr; +}; + +struct cil_roletype { + char *role_str; + void *role; /* role or attribute */ + char *type_str; + void *type; /* type, alias, or attribute */ +}; + +struct cil_type { + struct cil_symtab_datum datum; + struct cil_type *bounds; + int value; +}; + +#define CIL_ATTR_AVRULE (1 << 0) +#define CIL_ATTR_NEVERALLOW (1 << 1) +#define CIL_ATTR_CONSTRAINT (1 << 2) +#define CIL_ATTR_EXPAND_TRUE (1 << 3) +#define CIL_ATTR_EXPAND_FALSE (1 << 4) +struct cil_typeattribute { + struct cil_symtab_datum datum; + struct cil_list *expr_list; + ebitmap_t *types; + int used; // whether or not this attribute was used in a binary policy rule + int keep; +}; + +struct cil_typeattributeset { + char *attr_str; + struct cil_list *str_expr; + struct cil_list *datum_expr; +}; + +struct cil_expandtypeattribute { + struct cil_list *attr_strs; + struct cil_list *attr_datums; + int expand; +}; + +struct cil_typepermissive { + char *type_str; + void *type; /* type or alias */ +}; + +struct cil_name { + struct cil_symtab_datum datum; + char *name_str; +}; + +struct cil_nametypetransition { + char *src_str; + void *src; /* type, alias, or attribute */ + char *tgt_str; + void *tgt; /* type, alias, or attribute */ + char *obj_str; + struct cil_class *obj; + char *name_str; + struct cil_name *name; + char *result_str; + void *result; /* type or alias */ + +}; + +struct cil_rangetransition { + char *src_str; + void *src; /* type, alias, or attribute */ + char *exec_str; + void *exec; /* type, alias, or attribute */ + char *obj_str; + struct cil_class *obj; + char *range_str; + struct cil_levelrange *range; +}; + +struct cil_bool { + struct cil_symtab_datum datum; + uint16_t value; +}; + +struct cil_tunable { + struct cil_symtab_datum datum; + uint16_t value; +}; + +#define CIL_AVRULE_ALLOWED 1 +#define CIL_AVRULE_AUDITALLOW 2 +#define CIL_AVRULE_DONTAUDIT 8 +#define CIL_AVRULE_NEVERALLOW 128 +#define CIL_AVRULE_AV (AVRULE_ALLOWED | AVRULE_AUDITALLOW | AVRULE_DONTAUDIT | AVRULE_NEVERALLOW) +struct cil_avrule { + int is_extended; + uint32_t rule_kind; + char *src_str; + void *src; /* type, alias, or attribute */ + char *tgt_str; + void *tgt; /* type, alias, or attribute */ + union { + struct cil_list *classperms; + struct { + char *permx_str; + struct cil_permissionx *permx; + } x; + } perms; +}; + +#define CIL_PERMX_KIND_IOCTL 1 +struct cil_permissionx { + struct cil_symtab_datum datum; + uint32_t kind; + char *obj_str; + struct cil_class *obj; + struct cil_list *expr_str; + ebitmap_t *perms; +}; + +#define CIL_TYPE_TRANSITION 16 +#define CIL_TYPE_MEMBER 32 +#define CIL_TYPE_CHANGE 64 +#define CIL_AVRULE_TYPE (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE) +struct cil_type_rule { + uint32_t rule_kind; + char *src_str; + void *src; /* type, alias, or attribute */ + char *tgt_str; + void *tgt; /* type, alias, or attribute */ + char *obj_str; + struct cil_class *obj; + char *result_str; + void *result; /* type or alias */ +}; + +struct cil_roletransition { + char *src_str; + struct cil_role *src; + char *tgt_str; + void *tgt; /* type, alias, or attribute */ + char *obj_str; + struct cil_class *obj; + char *result_str; + struct cil_role *result; +}; + +struct cil_roleallow { + char *src_str; + void *src; /* role or attribute */ + char *tgt_str; + void *tgt; /* role or attribute */ +}; + +struct cil_sens { + struct cil_symtab_datum datum; + struct cil_list *cats_list; + uint32_t ordered; +}; + +struct cil_sensorder { + struct cil_list *sens_list_str; +}; + +struct cil_cat { + struct cil_symtab_datum datum; + uint32_t ordered; + int value; +}; + +struct cil_cats { + uint32_t evaluated; + struct cil_list *str_expr; + struct cil_list *datum_expr; +}; + +struct cil_catset { + struct cil_symtab_datum datum; + struct cil_cats *cats; +}; + +struct cil_catorder { + struct cil_list *cat_list_str; +}; + +struct cil_senscat { + char *sens_str; + struct cil_cats *cats; +}; + +struct cil_level { + struct cil_symtab_datum datum; + char *sens_str; + struct cil_sens *sens; + struct cil_cats *cats; +}; + +struct cil_levelrange { + struct cil_symtab_datum datum; + char *low_str; + struct cil_level *low; + char *high_str; + struct cil_level *high; +}; + +struct cil_context { + struct cil_symtab_datum datum; + char *user_str; + struct cil_user *user; + char *role_str; + struct cil_role *role; + char *type_str; + void *type; /* type or alias */ + char *range_str; + struct cil_levelrange *range; +}; + +enum cil_filecon_types { + CIL_FILECON_ANY = 0, + CIL_FILECON_FILE, + CIL_FILECON_DIR, + CIL_FILECON_CHAR, + CIL_FILECON_BLOCK, + CIL_FILECON_SOCKET, + CIL_FILECON_PIPE, + CIL_FILECON_SYMLINK, +}; + +struct cil_filecon { + char *path_str; + enum cil_filecon_types type; + char *context_str; + struct cil_context *context; +}; + +enum cil_protocol { + CIL_PROTOCOL_UDP = 1, + CIL_PROTOCOL_TCP, + CIL_PROTOCOL_DCCP, + CIL_PROTOCOL_SCTP +}; + +struct cil_ibpkeycon { + char *subnet_prefix_str; + uint32_t pkey_low; + uint32_t pkey_high; + char *context_str; + struct cil_context *context; +}; + +struct cil_portcon { + enum cil_protocol proto; + uint32_t port_low; + uint32_t port_high; + char *context_str; + struct cil_context *context; +}; + +struct cil_nodecon { + char *addr_str; + struct cil_ipaddr *addr; + char *mask_str; + struct cil_ipaddr *mask; + char *context_str; + struct cil_context *context; +}; + +struct cil_ipaddr { + struct cil_symtab_datum datum; + int family; + union { + struct in_addr v4; + struct in6_addr v6; + } ip; +}; + +struct cil_genfscon { + char *fs_str; + char *path_str; + enum cil_filecon_types file_type; + char *context_str; + struct cil_context *context; +}; + +struct cil_netifcon { + char *interface_str; + char *if_context_str; + struct cil_context *if_context; + char *packet_context_str; + struct cil_context *packet_context; + char *context_str; +}; + +struct cil_ibendportcon { + char *dev_name_str; + uint32_t port; + char *context_str; + struct cil_context *context; +}; +struct cil_pirqcon { + uint32_t pirq; + char *context_str; + struct cil_context *context; +}; + +struct cil_iomemcon { + uint64_t iomem_low; + uint64_t iomem_high; + char *context_str; + struct cil_context *context; +}; + +struct cil_ioportcon { + uint32_t ioport_low; + uint32_t ioport_high; + char *context_str; + struct cil_context *context; +}; + +struct cil_pcidevicecon { + uint32_t dev; + char *context_str; + struct cil_context *context; +}; + +struct cil_devicetreecon { + char *path; + char *context_str; + struct cil_context *context; +}; + + +/* Ensure that CIL uses the same values as sepol services.h */ +enum cil_fsuse_types { + CIL_FSUSE_XATTR = SECURITY_FS_USE_XATTR, + CIL_FSUSE_TASK = SECURITY_FS_USE_TASK, + CIL_FSUSE_TRANS = SECURITY_FS_USE_TRANS +}; + +struct cil_fsuse { + enum cil_fsuse_types type; + char *fs_str; + char *context_str; + struct cil_context *context; +}; + +#define CIL_MLS_LEVELS "l1 l2 h1 h2" +#define CIL_CONSTRAIN_KEYS "t1 t2 r1 r2 u1 u2" +#define CIL_MLSCONSTRAIN_KEYS CIL_MLS_LEVELS CIL_CONSTRAIN_KEYS +#define CIL_CONSTRAIN_OPER "== != eq dom domby incomp not and or" +struct cil_constrain { + struct cil_list *classperms; + struct cil_list *str_expr; + struct cil_list *datum_expr; +}; + +struct cil_validatetrans { + char *class_str; + struct cil_class *class; + struct cil_list *str_expr; + struct cil_list *datum_expr; +}; + +struct cil_param { + char *str; + enum cil_flavor flavor; +}; + +struct cil_macro { + struct cil_symtab_datum datum; + symtab_t symtab[CIL_SYM_NUM]; + struct cil_list *params; +}; + +struct cil_args { + char *arg_str; + struct cil_symtab_datum *arg; + char *param_str; + enum cil_flavor flavor; +}; + +struct cil_call { + char *macro_str; + struct cil_macro *macro; + struct cil_tree *args_tree; + struct cil_list *args; + int copied; +}; + +#define CIL_TRUE 1 +#define CIL_FALSE 0 + +struct cil_condblock { + enum cil_flavor flavor; + symtab_t symtab[CIL_SYM_NUM]; +}; + +struct cil_booleanif { + struct cil_list *str_expr; + struct cil_list *datum_expr; + int preserved_tunable; +}; + +struct cil_tunableif { + struct cil_list *str_expr; + struct cil_list *datum_expr; +}; + +struct cil_policycap { + struct cil_symtab_datum datum; +}; + +struct cil_bounds { + char *parent_str; + char *child_str; +}; + +/* Ensure that CIL uses the same values as sepol policydb.h */ +enum cil_default_object { + CIL_DEFAULT_SOURCE = DEFAULT_SOURCE, + CIL_DEFAULT_TARGET = DEFAULT_TARGET, +}; + +/* Default labeling behavior for users, roles, and types */ +struct cil_default { + enum cil_flavor flavor; + struct cil_list *class_strs; + struct cil_list *class_datums; + enum cil_default_object object; +}; + +/* Ensure that CIL uses the same values as sepol policydb.h */ +enum cil_default_object_range { + CIL_DEFAULT_SOURCE_LOW = DEFAULT_SOURCE_LOW, + CIL_DEFAULT_SOURCE_HIGH = DEFAULT_SOURCE_HIGH, + CIL_DEFAULT_SOURCE_LOW_HIGH = DEFAULT_SOURCE_LOW_HIGH, + CIL_DEFAULT_TARGET_LOW = DEFAULT_TARGET_LOW, + CIL_DEFAULT_TARGET_HIGH = DEFAULT_TARGET_HIGH, + CIL_DEFAULT_TARGET_LOW_HIGH = DEFAULT_TARGET_LOW_HIGH, + CIL_DEFAULT_GLBLUB = DEFAULT_GLBLUB, +}; + +/* Default labeling behavior for range */ +struct cil_defaultrange { + struct cil_list *class_strs; + struct cil_list *class_datums; + enum cil_default_object_range object_range; +}; + +struct cil_handleunknown { + int handle_unknown; +}; + +struct cil_mls { + int value; +}; + +struct cil_src_info { + char *kind; + uint32_t hll_line; + char *path; +}; + +void cil_db_init(struct cil_db **db); +void cil_db_destroy(struct cil_db **db); + +void cil_root_init(struct cil_root **root); +void cil_root_destroy(struct cil_root *root); + +void cil_destroy_data(void **data, enum cil_flavor flavor); + +int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *index); +const char * cil_node_to_string(struct cil_tree_node *node); + +int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size); +int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size); +int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size); + +void cil_symtab_array_init(symtab_t symtab[], const int symtab_sizes[CIL_SYM_NUM]); +void cil_symtab_array_destroy(symtab_t symtab[]); +void cil_destroy_ast_symtabs(struct cil_tree_node *root); +int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_sym_index sym_index); +int cil_string_to_uint32(const char *string, uint32_t *value, int base); +int cil_string_to_uint64(const char *string, uint64_t *value, int base); + +void cil_sort_init(struct cil_sort **sort); +void cil_sort_destroy(struct cil_sort **sort); +void cil_netifcon_init(struct cil_netifcon **netifcon); +void cil_ibendportcon_init(struct cil_ibendportcon **ibendportcon); +void cil_context_init(struct cil_context **context); +void cil_level_init(struct cil_level **level); +void cil_levelrange_init(struct cil_levelrange **lvlrange); +void cil_sens_init(struct cil_sens **sens); +void cil_block_init(struct cil_block **block); +void cil_blockinherit_init(struct cil_blockinherit **inherit); +void cil_blockabstract_init(struct cil_blockabstract **abstract); +void cil_in_init(struct cil_in **in); +void cil_class_init(struct cil_class **class); +void cil_classorder_init(struct cil_classorder **classorder); +void cil_classcommon_init(struct cil_classcommon **classcommon); +void cil_sid_init(struct cil_sid **sid); +void cil_sidcontext_init(struct cil_sidcontext **sidcontext); +void cil_sidorder_init(struct cil_sidorder **sidorder); +void cil_userrole_init(struct cil_userrole **userrole); +void cil_userprefix_init(struct cil_userprefix **userprefix); +void cil_selinuxuser_init(struct cil_selinuxuser **selinuxuser); +void cil_roleattribute_init(struct cil_roleattribute **attribute); +void cil_roleattributeset_init(struct cil_roleattributeset **attrset); +void cil_roletype_init(struct cil_roletype **roletype); +void cil_typeattribute_init(struct cil_typeattribute **attribute); +void cil_typeattributeset_init(struct cil_typeattributeset **attrset); +void cil_expandtypeattribute_init(struct cil_expandtypeattribute **expandattr); +void cil_alias_init(struct cil_alias **alias); +void cil_aliasactual_init(struct cil_aliasactual **aliasactual); +void cil_typepermissive_init(struct cil_typepermissive **typeperm); +void cil_name_init(struct cil_name **name); +void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans); +void cil_rangetransition_init(struct cil_rangetransition **rangetrans); +void cil_bool_init(struct cil_bool **cilbool); +void cil_boolif_init(struct cil_booleanif **bif); +void cil_condblock_init(struct cil_condblock **cb); +void cil_tunable_init(struct cil_tunable **ciltun); +void cil_tunif_init(struct cil_tunableif **tif); +void cil_avrule_init(struct cil_avrule **avrule); +void cil_permissionx_init(struct cil_permissionx **permx); +void cil_type_rule_init(struct cil_type_rule **type_rule); +void cil_roletransition_init(struct cil_roletransition **roletrans); +void cil_roleallow_init(struct cil_roleallow **role_allow); +void cil_catset_init(struct cil_catset **catset); +void cil_cats_init(struct cil_cats **cats); +void cil_senscat_init(struct cil_senscat **senscat); +void cil_filecon_init(struct cil_filecon **filecon); +void cil_ibpkeycon_init(struct cil_ibpkeycon **ibpkeycon); +void cil_portcon_init(struct cil_portcon **portcon); +void cil_nodecon_init(struct cil_nodecon **nodecon); +void cil_genfscon_init(struct cil_genfscon **genfscon); +void cil_pirqcon_init(struct cil_pirqcon **pirqcon); +void cil_iomemcon_init(struct cil_iomemcon **iomemcon); +void cil_ioportcon_init(struct cil_ioportcon **ioportcon); +void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon); +void cil_devicetreecon_init(struct cil_devicetreecon **devicetreecon); +void cil_fsuse_init(struct cil_fsuse **fsuse); +void cil_constrain_init(struct cil_constrain **constrain); +void cil_validatetrans_init(struct cil_validatetrans **validtrans); +void cil_ipaddr_init(struct cil_ipaddr **ipaddr); +void cil_perm_init(struct cil_perm **perm); +void cil_classpermission_init(struct cil_classpermission **cp); +void cil_classpermissionset_init(struct cil_classpermissionset **cps); +void cil_classperms_set_init(struct cil_classperms_set **cp_set); +void cil_classperms_init(struct cil_classperms **cp); +void cil_classmapping_init(struct cil_classmapping **mapping); +void cil_user_init(struct cil_user **user); +void cil_userlevel_init(struct cil_userlevel **usrlvl); +void cil_userrange_init(struct cil_userrange **userrange); +void cil_role_init(struct cil_role **role); +void cil_type_init(struct cil_type **type); +void cil_cat_init(struct cil_cat **cat); +void cil_catorder_init(struct cil_catorder **catorder); +void cil_sensorder_init(struct cil_sensorder **sensorder); +void cil_args_init(struct cil_args **args); +void cil_call_init(struct cil_call **call); +void cil_optional_init(struct cil_optional **optional); +void cil_param_init(struct cil_param **param); +void cil_macro_init(struct cil_macro **macro); +void cil_policycap_init(struct cil_policycap **policycap); +void cil_bounds_init(struct cil_bounds **bounds); +void cil_default_init(struct cil_default **def); +void cil_defaultrange_init(struct cil_defaultrange **def); +void cil_handleunknown_init(struct cil_handleunknown **unk); +void cil_mls_init(struct cil_mls **mls); +void cil_src_info_init(struct cil_src_info **info); +void cil_userattribute_init(struct cil_userattribute **attribute); +void cil_userattributeset_init(struct cil_userattributeset **attrset); + +#endif diff --git a/kernel/libsepol/cil/src/cil_lexer.h b/kernel/libsepol/cil/src/cil_lexer.h new file mode 100644 index 00000000..ab555d84 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_lexer.h @@ -0,0 +1,55 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_LEXER_H_ +#define CIL_LEXER_H_ + +#include + +#define OPAREN 1 +#define CPAREN 2 +#define SYMBOL 3 +#define QSTRING 4 +#define COMMENT 5 +#define HLL_LINEMARK 6 +#define NEWLINE 7 +#define END_OF_FILE 8 +#define UNKNOWN 9 + +struct token { + uint32_t type; + char * value; + uint32_t line; +}; + +int cil_lexer_setup(char *buffer, uint32_t size); +void cil_lexer_destroy(void); +int cil_lexer_next(struct token *tok); + +#endif /* CIL_LEXER_H_ */ diff --git a/kernel/libsepol/cil/src/cil_lexer.l b/kernel/libsepol/cil/src/cil_lexer.l new file mode 100644 index 00000000..8bf2b6e7 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_lexer.l @@ -0,0 +1,94 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +%{ + #include + #include + #include "cil_internal.h" + #include "cil_lexer.h" + #include "cil_log.h" + #include "cil_mem.h" + char *value = NULL; + int line = 1; +%} + +%option nounput +%option noinput +%option noyywrap +%option prefix="cil_yy" + +digit [0-9] +alpha [a-zA-Z] +spec_char [\[\]\.\@\=\/\*\-\_\$\%\+\-\!\|\&\^\:\~\`\#\{\}\'\<\>\?\,] +symbol ({digit}|{alpha}|{spec_char})+ +white [ \t] +newline [\n\r] +qstring \"[^"\n\0]*\" +hll_lm ^;;\* +comment ; + +%% +{newline} line++; return NEWLINE; +{hll_lm} value=yytext; return HLL_LINEMARK; +{comment} value=yytext; return COMMENT; +"(" value=yytext; return OPAREN; +")" value=yytext; return CPAREN; +{symbol} value=yytext; return SYMBOL; +{white} ; +{qstring} value=yytext; return QSTRING; +<> return END_OF_FILE; +. value=yytext; return UNKNOWN; +%% + +int cil_lexer_setup(char *buffer, uint32_t size) +{ + size = (yy_size_t)size; + if (yy_scan_buffer(buffer, size) == NULL) { + cil_log(CIL_INFO, "Lexer failed to setup buffer\n"); + return SEPOL_ERR; + } + + line = 1; + + return SEPOL_OK; +} + +void cil_lexer_destroy(void) +{ + yylex_destroy(); +} + +int cil_lexer_next(struct token *tok) +{ + tok->type = yylex(); + tok->value = value; + tok->line = line; + + return SEPOL_OK; +} diff --git a/kernel/libsepol/cil/src/cil_list.c b/kernel/libsepol/cil/src/cil_list.c new file mode 100644 index 00000000..85446b4c --- /dev/null +++ b/kernel/libsepol/cil/src/cil_list.c @@ -0,0 +1,278 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_mem.h" + +__attribute__((noreturn)) __attribute__((format (printf, 1, 2))) static void cil_list_error(const char* msg, ...) +{ + va_list ap; + va_start(ap, msg); + cil_vlog(CIL_ERR, msg, ap); + va_end(ap); + exit(1); +} + +void cil_list_init(struct cil_list **list, enum cil_flavor flavor) +{ + struct cil_list *new_list = cil_malloc(sizeof(*new_list)); + new_list->head = NULL; + new_list->tail = NULL; + new_list->flavor = flavor; + *list = new_list; +} + +void cil_list_destroy(struct cil_list **list, unsigned destroy_data) +{ + struct cil_list_item *item; + + if (*list == NULL) { + return; + } + + item = (*list)->head; + while (item != NULL) + { + struct cil_list_item *next = item->next; + if (item->flavor == CIL_LIST) { + cil_list_destroy((struct cil_list**)&(item->data), destroy_data); + free(item); + } else { + cil_list_item_destroy(&item, destroy_data); + } + item = next; + } + free(*list); + *list = NULL; +} + +void cil_list_item_init(struct cil_list_item **item) +{ + struct cil_list_item *new_item = cil_malloc(sizeof(*new_item)); + new_item->next = NULL; + new_item->flavor = CIL_NONE; + new_item->data = NULL; + + *item = new_item; +} + +void cil_list_item_destroy(struct cil_list_item **item, unsigned destroy_data) +{ + if (destroy_data) { + cil_destroy_data(&(*item)->data, (*item)->flavor); + } + free(*item); + *item = NULL; +} + +void cil_list_append(struct cil_list *list, enum cil_flavor flavor, void *data) +{ + struct cil_list_item *item; + + if (list == NULL) { + cil_list_error("Attempt to append data to a NULL list"); + } + + cil_list_item_init(&item); + item->flavor = flavor; + item->data = data; + + if (list->tail == NULL) { + list->head = item; + list->tail = item; + return; + } + + list->tail->next = item; + list->tail = item; +} + +void cil_list_prepend(struct cil_list *list, enum cil_flavor flavor, void *data) +{ + struct cil_list_item *item; + + if (list == NULL) { + cil_list_error("Attempt to prepend data to a NULL list"); + } + + cil_list_item_init(&item); + item->flavor = flavor; + item->data = data; + + if (list->tail == NULL) { + list->head = item; + list->tail = item; + return; + } + + item->next = list->head; + list->head = item; +} + +struct cil_list_item *cil_list_insert(struct cil_list *list, struct cil_list_item *curr, enum cil_flavor flavor, void *data) +{ + struct cil_list_item *item; + + if (list == NULL) { + cil_list_error("Attempt to append data to a NULL list"); + } + + if (curr == NULL) { + /* Insert at the front of the list */ + cil_list_prepend(list, flavor, data); + return list->head; + } + + if (curr == list->tail) { + cil_list_append(list, flavor, data); + return list->tail; + } + + cil_list_item_init(&item); + item->flavor = flavor; + item->data = data; + item->next = curr->next; + + curr->next = item; + + return item; +} + +void cil_list_append_item(struct cil_list *list, struct cil_list_item *item) +{ + struct cil_list_item *last = item; + + if (list == NULL) { + cil_list_error("Attempt to append an item to a NULL list"); + } + + if (item == NULL) { + cil_list_error("Attempt to append a NULL item to a list"); + } + + while (last->next != NULL) { + last = last->next; + } + + if (list->tail == NULL) { + list->head = item; + list->tail = last; + return; + } + + list->tail->next = item; + list->tail = last; + +} + +void cil_list_prepend_item(struct cil_list *list, struct cil_list_item *item) +{ + struct cil_list_item *last = item; + + if (list == NULL) { + cil_list_error("Attempt to prepend an item to a NULL list"); + } + + if (item == NULL) { + cil_list_error("Attempt to prepend a NULL item to a list"); + } + + while (last->next != NULL) { + last = last->next; + } + + if (list->tail == NULL) { + list->head = item; + list->tail = last; + return; + } + + last->next = list->head; + list->head = item; +} + +void cil_list_remove(struct cil_list *list, enum cil_flavor flavor, void *data, unsigned destroy_data) +{ + struct cil_list_item *item; + struct cil_list_item *previous = NULL; + + if (list == NULL) { + cil_list_error("Attempt to remove data from a NULL list"); + } + + cil_list_for_each(item, list) { + if (item->data == data && item->flavor == flavor) { + if (previous == NULL) { + list->head = item->next; + } else { + previous->next = item->next; + } + if (item->next == NULL) { + list->tail = previous; + } + cil_list_item_destroy(&item, destroy_data); + break; + } + previous = item; + } +} + +int cil_list_contains(struct cil_list *list, void *data) +{ + struct cil_list_item *curr = NULL; + + cil_list_for_each(curr, list) { + if (curr->data == data) { + return CIL_TRUE; + } + } + + return CIL_FALSE; +} + +int cil_list_match_any(struct cil_list *l1, struct cil_list *l2) +{ + struct cil_list_item *i1; + struct cil_list_item *i2; + + cil_list_for_each(i1, l1) { + cil_list_for_each(i2, l2) { + if (i1->data == i2->data && i1->flavor == i2->flavor) { + return CIL_TRUE; + } + } + } + + return CIL_FALSE; +} diff --git a/kernel/libsepol/cil/src/cil_list.h b/kernel/libsepol/cil/src/cil_list.h new file mode 100644 index 00000000..6b4708a0 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_list.h @@ -0,0 +1,64 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_LIST_H_ +#define CIL_LIST_H_ + +#include "cil_flavor.h" + +struct cil_list { + struct cil_list_item *head; + struct cil_list_item *tail; + enum cil_flavor flavor; +}; + +struct cil_list_item { + struct cil_list_item *next; + enum cil_flavor flavor; + void *data; +}; + +#define cil_list_for_each(item, list) \ + for (item = (list)->head; item != NULL; item = item->next) + + +void cil_list_init(struct cil_list **list, enum cil_flavor flavor); +void cil_list_destroy (struct cil_list **list, unsigned destroy_data); +void cil_list_item_init(struct cil_list_item **item); +void cil_list_item_destroy(struct cil_list_item **item, unsigned destroy_data); +void cil_list_append(struct cil_list *list, enum cil_flavor flavor, void *data); +void cil_list_prepend(struct cil_list *list, enum cil_flavor flavor, void *data); +void cil_list_remove(struct cil_list *list, enum cil_flavor flavor, void *data, unsigned destroy_data); +struct cil_list_item *cil_list_insert(struct cil_list *list, struct cil_list_item *curr, enum cil_flavor flavor, void *data); +void cil_list_append_item(struct cil_list *list, struct cil_list_item *item); +void cil_list_prepend_item(struct cil_list *list, struct cil_list_item *item); +int cil_list_contains(struct cil_list *list, void *data); +int cil_list_match_any(struct cil_list *l1, struct cil_list *l2); + +#endif diff --git a/kernel/libsepol/cil/src/cil_log.c b/kernel/libsepol/cil/src/cil_log.c new file mode 100644 index 00000000..f4c6e415 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_log.c @@ -0,0 +1,82 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include + +#include +#include "cil_log.h" + +static enum cil_log_level cil_log_level = CIL_ERR; + +static void cil_default_log_handler(__attribute__((unused)) int lvl, const char *msg) +{ + fprintf(stderr, "%s", msg); +} + +static void (*cil_log_handler)(int lvl, const char *msg) = &cil_default_log_handler; + +void cil_set_log_handler(void (*handler)(int lvl, const char *msg)) +{ + cil_log_handler = handler; +} + +__attribute__ ((format (printf, 2, 0))) void cil_vlog(enum cil_log_level lvl, const char *msg, va_list args) +{ + if (cil_log_level >= lvl) { + char buff[MAX_LOG_SIZE]; + int n = vsnprintf(buff, MAX_LOG_SIZE, msg, args); + if (n > 0) { + (*cil_log_handler)(cil_log_level, buff); + if (n >= MAX_LOG_SIZE) { + (*cil_log_handler)(cil_log_level, " "); + } + } + } +} + +__attribute__ ((format (printf, 2, 3))) void cil_log(enum cil_log_level lvl, const char *msg, ...) +{ + va_list args; + va_start(args, msg); + cil_vlog(lvl, msg, args); + va_end(args); +} + +void cil_set_log_level(enum cil_log_level lvl) +{ + cil_log_level = lvl; +} + +enum cil_log_level cil_get_log_level(void) +{ + return cil_log_level; +} diff --git a/kernel/libsepol/cil/src/cil_log.h b/kernel/libsepol/cil/src/cil_log.h new file mode 100644 index 00000000..442781fb --- /dev/null +++ b/kernel/libsepol/cil/src/cil_log.h @@ -0,0 +1,43 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ +#ifndef CIL_LOG_H_ +#define CIL_LOG_H_ + +#include +#include +#include + +#define MAX_LOG_SIZE 512 + +__attribute__ ((format(printf, 2, 0))) void cil_vlog(enum cil_log_level lvl, const char *msg, va_list args); +__attribute__ ((format(printf, 2, 3))) void cil_log(enum cil_log_level lvl, const char *msg, ...); + +enum cil_log_level cil_get_log_level(void); + +#endif // CIL_LOG_H_ diff --git a/kernel/libsepol/cil/src/cil_mem.c b/kernel/libsepol/cil/src/cil_mem.c new file mode 100644 index 00000000..8e4a1d24 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_mem.c @@ -0,0 +1,110 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include + +#include "cil_log.h" +#include "cil_mem.h" + +void *cil_malloc(size_t size) +{ + void *mem = malloc(size); + if (mem == NULL){ + if (size == 0) { + return NULL; + } + cil_log(CIL_ERR, "Failed to allocate memory\n"); + exit(1); + } + + return mem; +} + +void *cil_calloc(size_t num_elements, size_t element_size) +{ + void *mem = calloc(num_elements, element_size); + if (mem == NULL){ + cil_log(CIL_ERR, "Failed to allocate memory\n"); + exit(1); + } + + return mem; +} + +void *cil_realloc(void *ptr, size_t size) +{ + void *mem = realloc(ptr, size); + if (mem == NULL){ + if (size == 0) { + return NULL; + } + cil_log(CIL_ERR, "Failed to allocate memory\n"); + exit(1); + } + + return mem; +} + + +char *cil_strdup(const char *str) +{ + char *mem = NULL; + + if (str == NULL) { + return NULL; + } + + mem = strdup(str); + if (mem == NULL) { + cil_log(CIL_ERR, "Failed to allocate memory\n"); + exit(1); + } + + return mem; +} + +__attribute__ ((format (printf, 2, 3))) int cil_asprintf(char **strp, const char *fmt, ...) +{ + int rc; + va_list ap; + + va_start(ap, fmt); + rc = vasprintf(strp, fmt, ap); + va_end(ap); + + if (rc == -1) { + cil_log(CIL_ERR, "Failed to allocate memory\n"); + exit(1); + } + + return rc; +} diff --git a/kernel/libsepol/cil/src/cil_mem.h b/kernel/libsepol/cil/src/cil_mem.h new file mode 100644 index 00000000..794f02a3 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_mem.h @@ -0,0 +1,41 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_MEM_H_ +#define CIL_MEM_H_ + +/* Wrapped malloc that catches errors and calls the error callback */ +void *cil_malloc(size_t size); +void *cil_calloc(size_t num_elements, size_t element_size); +void *cil_realloc(void *ptr, size_t size); +char *cil_strdup(const char *str); +int cil_asprintf(char **strp, const char *fmt, ...); + +#endif /* CIL_MEM_H_ */ + diff --git a/kernel/libsepol/cil/src/cil_parser.c b/kernel/libsepol/cil/src/cil_parser.c new file mode 100644 index 00000000..5375d49a --- /dev/null +++ b/kernel/libsepol/cil/src/cil_parser.c @@ -0,0 +1,331 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include +#include + +#include "cil_internal.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_lexer.h" +#include "cil_parser.h" +#include "cil_strpool.h" +#include "cil_stack.h" + +#define CIL_PARSER_MAX_EXPR_DEPTH (0x1 << 12) + +struct hll_info { + uint32_t hll_offset; + uint32_t hll_expand; +}; + +static void push_hll_info(struct cil_stack *stack, uint32_t hll_offset, uint32_t hll_expand) +{ + struct hll_info *new = cil_malloc(sizeof(*new)); + + new->hll_offset = hll_offset; + new->hll_expand = hll_expand; + + cil_stack_push(stack, CIL_NONE, new); +} + +static void pop_hll_info(struct cil_stack *stack, uint32_t *hll_offset, uint32_t *hll_expand) +{ + struct cil_stack_item *curr = cil_stack_pop(stack); + struct hll_info *info; + + if (!curr) { + return; + } + info = curr->data; + *hll_expand = info->hll_expand; + *hll_offset = info->hll_offset; + free(curr->data); +} + +static void create_node(struct cil_tree_node **node, struct cil_tree_node *current, uint32_t line, uint32_t hll_offset, void *value) +{ + cil_tree_node_init(node); + (*node)->parent = current; + (*node)->flavor = CIL_NODE; + (*node)->line = line; + (*node)->hll_offset = hll_offset; + (*node)->data = value; +} + +static void insert_node(struct cil_tree_node *node, struct cil_tree_node *current) +{ + if (current->cl_head == NULL) { + current->cl_head = node; + } else { + current->cl_tail->next = node; + } + current->cl_tail = node; +} + +static int add_hll_linemark(struct cil_tree_node **current, uint32_t *hll_offset, uint32_t *hll_expand, struct cil_stack *stack, char *path) +{ + char *hll_type; + struct cil_tree_node *node; + struct token tok; + uint32_t prev_hll_expand, prev_hll_offset; + + cil_lexer_next(&tok); + if (tok.type != SYMBOL) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + hll_type = cil_strpool_add(tok.value); + if (hll_type != CIL_KEY_SRC_HLL_LME && hll_type != CIL_KEY_SRC_HLL_LMS && hll_type != CIL_KEY_SRC_HLL_LMX) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + if (hll_type == CIL_KEY_SRC_HLL_LME) { + if (cil_stack_is_empty(stack)) { + cil_log(CIL_ERR, "Line mark end without start\n"); + goto exit; + } + prev_hll_expand = *hll_expand; + prev_hll_offset = *hll_offset; + pop_hll_info(stack, hll_offset, hll_expand); + if (!*hll_expand) { + /* This is needed if not going back to an lmx section. */ + *hll_offset = prev_hll_offset; + } + if (prev_hll_expand && !*hll_expand) { + /* This is needed to count the lme at the end of an lmx section + * within an lms section (or within no hll section). + */ + (*hll_offset)++; + } + *current = (*current)->parent; + } else { + push_hll_info(stack, *hll_offset, *hll_expand); + if (cil_stack_number_of_items(stack) > CIL_PARSER_MAX_EXPR_DEPTH) { + cil_log(CIL_ERR, "Number of active line marks exceeds limit of %d\n", CIL_PARSER_MAX_EXPR_DEPTH); + goto exit; + } + + create_node(&node, *current, tok.line, *hll_offset, NULL); + insert_node(node, *current); + *current = node; + + create_node(&node, *current, tok.line, *hll_offset, CIL_KEY_SRC_INFO); + insert_node(node, *current); + + create_node(&node, *current, tok.line, *hll_offset, hll_type); + insert_node(node, *current); + + cil_lexer_next(&tok); + if (tok.type != SYMBOL) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + + create_node(&node, *current, tok.line, *hll_offset, cil_strpool_add(tok.value)); + insert_node(node, *current); + + cil_lexer_next(&tok); + if (tok.type != SYMBOL && tok.type != QSTRING) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + + if (tok.type == QSTRING) { + tok.value[strlen(tok.value) - 1] = '\0'; + tok.value = tok.value+1; + } + + create_node(&node, *current, tok.line, *hll_offset, cil_strpool_add(tok.value)); + insert_node(node, *current); + + *hll_expand = (hll_type == CIL_KEY_SRC_HLL_LMX) ? 1 : 0; + } + + cil_lexer_next(&tok); + if (tok.type != NEWLINE) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + + if (!*hll_expand) { + /* Need to increment because of the NEWLINE */ + (*hll_offset)++; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Problem with high-level line mark at line %u of %s\n", tok.line, path); + return SEPOL_ERR; +} + +static void add_cil_path(struct cil_tree_node **current, char *path) +{ + struct cil_tree_node *node; + + create_node(&node, *current, 0, 0, NULL); + insert_node(node, *current); + *current = node; + + create_node(&node, *current, 0, 0, CIL_KEY_SRC_INFO); + insert_node(node, *current); + + create_node(&node, *current, 0, 0, CIL_KEY_SRC_CIL); + insert_node(node, *current); + + create_node(&node, *current, 0, 0, cil_strpool_add("1")); + insert_node(node, *current); + + create_node(&node, *current, 0, 0, path); + insert_node(node, *current); +} + +int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree **parse_tree) +{ + + int paren_count = 0; + + struct cil_tree *tree = NULL; + struct cil_tree_node *node = NULL; + struct cil_tree_node *current = NULL; + char *path = cil_strpool_add(_path); + struct cil_stack *stack; + uint32_t hll_offset = 1; + uint32_t hll_expand = 0; + struct token tok; + int rc = SEPOL_OK; + + cil_stack_init(&stack); + + cil_lexer_setup(buffer, size); + + tree = *parse_tree; + current = tree->root; + + add_cil_path(¤t, path); + + do { + cil_lexer_next(&tok); + switch (tok.type) { + case HLL_LINEMARK: + rc = add_hll_linemark(¤t, &hll_offset, &hll_expand, stack, path); + if (rc != SEPOL_OK) { + goto exit; + } + break; + case OPAREN: + paren_count++; + if (paren_count > CIL_PARSER_MAX_EXPR_DEPTH) { + cil_log(CIL_ERR, "Number of open parenthesis exceeds limit of %d at line %d of %s\n", CIL_PARSER_MAX_EXPR_DEPTH, tok.line, path); + goto exit; + } + create_node(&node, current, tok.line, hll_offset, NULL); + insert_node(node, current); + current = node; + break; + case CPAREN: + paren_count--; + if (paren_count < 0) { + cil_log(CIL_ERR, "Close parenthesis without matching open at line %d of %s\n", tok.line, path); + goto exit; + } + current = current->parent; + break; + case QSTRING: + tok.value[strlen(tok.value) - 1] = '\0'; + tok.value = tok.value+1; + /* FALLTHRU */ + case SYMBOL: + if (paren_count == 0) { + cil_log(CIL_ERR, "Symbol not inside parenthesis at line %d of %s\n", tok.line, path); + goto exit; + } + + create_node(&node, current, tok.line, hll_offset, cil_strpool_add(tok.value)); + insert_node(node, current); + break; + case NEWLINE : + if (!hll_expand) { + hll_offset++; + } + break; + case COMMENT: + while (tok.type != NEWLINE && tok.type != END_OF_FILE) { + cil_lexer_next(&tok); + } + if (!hll_expand) { + hll_offset++; + } + if (tok.type != END_OF_FILE) { + break; + } + /* FALLTHRU */ + // Fall through if EOF + case END_OF_FILE: + if (paren_count > 0) { + cil_log(CIL_ERR, "Open parenthesis without matching close at line %d of %s\n", tok.line, path); + goto exit; + } + if (!cil_stack_is_empty(stack)) { + cil_log(CIL_ERR, "High-level language line marker start without close at line %d of %s\n", tok.line, path); + goto exit; + } + break; + case UNKNOWN: + cil_log(CIL_ERR, "Invalid token '%s' at line %d of %s\n", tok.value, tok.line, path); + goto exit; + default: + cil_log(CIL_ERR, "Unknown token type '%d' at line %d of %s\n", tok.type, tok.line, path); + goto exit; + } + } + while (tok.type != END_OF_FILE); + + cil_lexer_destroy(); + + cil_stack_destroy(&stack); + + *parse_tree = tree; + + return SEPOL_OK; + +exit: + while (!cil_stack_is_empty(stack)) { + pop_hll_info(stack, &hll_offset, &hll_expand); + } + cil_lexer_destroy(); + cil_stack_destroy(&stack); + + return SEPOL_ERR; +} diff --git a/kernel/libsepol/cil/src/cil_parser.h b/kernel/libsepol/cil/src/cil_parser.h new file mode 100644 index 00000000..1cec6394 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_parser.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_PARSER_H_ +#define CIL_PARSER_H_ + +#include "cil_tree.h" + +int cil_parser(const char *path, char *buffer, uint32_t size, struct cil_tree **parse_tree); + +#endif /* CIL_PARSER_H_ */ diff --git a/kernel/libsepol/cil/src/cil_policy.c b/kernel/libsepol/cil/src/cil_policy.c new file mode 100644 index 00000000..c6be8d43 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_policy.c @@ -0,0 +1,1989 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_find.h" +#include "cil_mem.h" +#include "cil_policy.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_symtab.h" + + +enum cil_statement_list { + CIL_LIST_COMMON = 1, + CIL_LIST_DEFAULT_USER, + CIL_LIST_DEFAULT_ROLE, + CIL_LIST_DEFAULT_TYPE, + CIL_LIST_DEFAULT_RANGE, + CIL_LIST_SENSALIAS, + CIL_LIST_CATALIAS, + CIL_LIST_MLSCONSTRAIN, + CIL_LIST_MLSVALIDATETRANS, + CIL_LIST_POLICYCAP, + CIL_LIST_TYPEATTRIBUTE, + CIL_LIST_ROLEATTRIBUTE, + CIL_LIST_BOOL, + CIL_LIST_TYPE, + CIL_LIST_TYPEALIAS, + CIL_LIST_ROLE, + CIL_LIST_ROLEALLOW, + CIL_LIST_ROLETRANSITION, + CIL_LIST_USER, + CIL_LIST_CONSTRAINT, + CIL_LIST_VALIDATETRANS, + CIL_LIST_NUM_LISTS +}; + +static int __cil_gather_statements_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + struct cil_list **lists; + int kind = 0; + + lists = (struct cil_list **)extra_args; + + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_BOOLEANIF: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_COMMON: + kind = CIL_LIST_COMMON; + break; + case CIL_DEFAULTUSER: + kind = CIL_LIST_DEFAULT_USER; + break; + case CIL_DEFAULTROLE: + kind = CIL_LIST_DEFAULT_ROLE; + break; + case CIL_DEFAULTTYPE: + kind = CIL_LIST_DEFAULT_TYPE; + break; + case CIL_DEFAULTRANGE: + kind = CIL_LIST_DEFAULT_RANGE; + break; + case CIL_SENSALIAS: + kind = CIL_LIST_SENSALIAS; + break; + case CIL_CATALIAS: + kind = CIL_LIST_CATALIAS; + break; + case CIL_MLSCONSTRAIN: + kind = CIL_LIST_MLSCONSTRAIN; + break; + case CIL_MLSVALIDATETRANS: + kind = CIL_LIST_MLSVALIDATETRANS; + break; + case CIL_POLICYCAP: + kind = CIL_LIST_POLICYCAP; + break; + case CIL_TYPEATTRIBUTE: { + struct cil_typeattribute *attr = node->data; + if (strcmp(attr->datum.fqn, "cil_gen_require") != 0) { + kind = CIL_LIST_TYPEATTRIBUTE; + } + break; + } + case CIL_ROLEATTRIBUTE: { + struct cil_roleattribute *attr = node->data; + if (strcmp(attr->datum.fqn, "cil_gen_require") != 0) { + kind = CIL_LIST_ROLEATTRIBUTE; + } + break; + } + case CIL_BOOL: + kind = CIL_LIST_BOOL; + break; + case CIL_TYPE: + kind = CIL_LIST_TYPE; + break; + case CIL_TYPEALIAS: + kind = CIL_LIST_TYPEALIAS; + break; + case CIL_ROLE: { + struct cil_role *role = node->data; + if (strcmp(role->datum.fqn, "object_r") != 0) { + kind = CIL_LIST_ROLE; + } + break; + } + case CIL_ROLEALLOW: + kind = CIL_LIST_ROLEALLOW; + break; + case CIL_ROLETRANSITION: + kind = CIL_LIST_ROLETRANSITION; + break; + case CIL_USER: + kind = CIL_LIST_USER; + break; + case CIL_CONSTRAIN: + kind = CIL_LIST_CONSTRAINT; + break; + case CIL_VALIDATETRANS: + kind = CIL_LIST_VALIDATETRANS; + break; + default: + break; + } + + if (kind > 0) { + cil_list_append(lists[kind], node->flavor, node->data); + } + + return SEPOL_OK; +} + +static void cil_gather_statements(struct cil_tree_node *start, struct cil_list *lists[]) +{ + cil_tree_walk(start, __cil_gather_statements_helper, NULL, NULL, lists); +} + +static void cil_simple_rules_to_policy(FILE *out, struct cil_list *rules, const char *kind) +{ + struct cil_list_item *i1; + + cil_list_for_each(i1, rules) { + fprintf(out, "%s %s;\n", kind, DATUM(i1->data)->fqn); + } +} + +static void cil_cats_to_policy(FILE *out, struct cil_cats *cats) +{ + const char *lead = ""; + struct cil_cat *first = NULL, *last = NULL, *cat; + struct cil_list_item *i1; + + cil_list_for_each(i1, cats->datum_expr) { + cat = i1->data; + if (first == NULL) { + first = cat; + } else if (last == NULL) { + if (cat->value == first->value + 1) { + last = cat; + } else { + fprintf(out, "%s%s", lead, DATUM(first)->fqn); + lead = ","; + first = cat; + } + } else if (cat->value == last->value + 1) { + last = cat; + } else { + fprintf(out, "%s%s", lead, DATUM(first)->fqn); + lead = ","; + if (last->value >= first->value + 1) { + fprintf(out, "."); + } else { + fprintf(out, ","); + } + fprintf(out, "%s", DATUM(last)->fqn); + first = cat; + last = NULL; + } + } + if (first) { + fprintf(out, "%s%s", lead, DATUM(first)->fqn); + if (last != NULL) { + if (last->value >= first->value + 1) { + fprintf(out, "."); + } else { + fprintf(out, ","); + } + fprintf(out, "%s", DATUM(last)->fqn); + } + } +} + +static void cil_level_to_policy(FILE *out, struct cil_level *level) +{ + fprintf(out, "%s", DATUM(level->sens)->fqn); + if (level->cats != NULL) { + fprintf(out, ":"); + cil_cats_to_policy(out, level->cats); + } +} + +static int cil_levels_simple_and_equal(struct cil_level *l1, struct cil_level *l2) +{ + /* Mostly just want to detect s0 - s0 ranges */ + if (l1 == l2) + return CIL_TRUE; + + if (l1->sens == l2->sens && (l1->cats == NULL && l2->cats == NULL)) + return CIL_TRUE; + + return CIL_FALSE; +} + +static void cil_levelrange_to_policy(FILE *out, struct cil_levelrange *lvlrange) +{ + cil_level_to_policy(out, lvlrange->low); + if (cil_levels_simple_and_equal(lvlrange->low, lvlrange->high) == CIL_FALSE) { + fprintf(out, " - "); + cil_level_to_policy(out, lvlrange->high); + } +} + +static void cil_context_to_policy(FILE *out, struct cil_context *context, int mls) +{ + fprintf(out, "%s:", DATUM(context->user)->fqn); + fprintf(out, "%s:", DATUM(context->role)->fqn); + fprintf(out, "%s", DATUM(context->type)->fqn); + if (mls) { + fprintf(out, ":"); + cil_levelrange_to_policy(out, context->range); + } +} + +static void cil_cond_expr_to_policy(FILE *out, struct cil_list *expr, int first) +{ + struct cil_list_item *i1 = expr->head; + + if (i1->flavor == CIL_OP) { + enum cil_flavor op = (enum cil_flavor)(uintptr_t)i1->data; + fprintf(out, "("); + switch (op) { + case CIL_NOT: + fprintf(out, "! "); + cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE); + break; + case CIL_OR: + cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE); + fprintf(out, " || "); + cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE); + break; + case CIL_AND: + cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE); + fprintf(out, " && "); + cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE); + break; + case CIL_XOR: + cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE); + fprintf(out, " ^ "); + cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE); + break; + case CIL_EQ: + cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE); + fprintf(out, " == "); + cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE); + break; + case CIL_NEQ: + cil_cond_expr_to_policy(out, i1->next->data, CIL_FALSE); + fprintf(out, " != "); + cil_cond_expr_to_policy(out, i1->next->next->data, CIL_FALSE); + break; + default: + fprintf(out, "???"); + break; + } + fprintf(out, ")"); + } else if (i1->flavor == CIL_DATUM) { + if (first == CIL_TRUE) { + fprintf(out, "("); + } + fprintf(out, "%s", DATUM(i1->data)->fqn); + if (first == CIL_TRUE) { + fprintf(out, ")"); + } + } else if (i1->flavor == CIL_LIST) { + cil_cond_expr_to_policy(out, i1->data, CIL_FALSE); + } else { + fprintf(out, "???"); + } +} + +static size_t __cil_userattribute_len(struct cil_db *db, struct cil_userattribute *attr) +{ + ebitmap_node_t *unode; + unsigned int i; + size_t len = 0; + + ebitmap_for_each_positive_bit(attr->users, unode, i) { + len += strlen(DATUM(db->val_to_user[i])->fqn); + len++; + } + + return len; +} + +static size_t __cil_cons_leaf_operand_len(struct cil_db *db, struct cil_list_item *operand) +{ + struct cil_list_item *i1; + enum cil_flavor flavor = operand->flavor; + size_t len = 0; + + if (flavor == CIL_CONS_OPERAND) { + len = 2; + } else if (flavor == CIL_DATUM) { + struct cil_tree_node *node = NODE(operand->data); + if (node->flavor == CIL_USERATTRIBUTE) { + len = __cil_userattribute_len(db, operand->data); + len++; /* "{" */ + } else { + len = strlen(DATUM(operand->data)->fqn); + } + } else if (flavor == CIL_LIST) { + len = 1; /* "{" */ + cil_list_for_each(i1, (struct cil_list *)operand->data) { + struct cil_tree_node *node = NODE(operand->data); + if (node->flavor == CIL_USERATTRIBUTE) { + len = __cil_userattribute_len(db, operand->data); + } else { + len += strlen(DATUM(operand->data)->fqn); + len++; /* " " or "}" */ + } + } + } + + return len; +} + +static size_t __cil_cons_leaf_op_len(struct cil_list_item *op) +{ + enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data; + size_t len; + + switch (flavor) { + case CIL_EQ: + len = 4; /* " == " */ + break; + case CIL_NEQ: + len = 4; /* " != " */ + break; + case CIL_CONS_DOM: + len = 5; /* " dom " */ + break; + case CIL_CONS_DOMBY: + len = 7; /* " domby " */ + break; + case CIL_CONS_INCOMP: + len = 8; /* " incomp " */ + break; + default: + /* Should be impossible to be here */ + len = 5; /* " ??? " */ + } + + return len; +} + +static size_t cil_cons_expr_len(struct cil_db *db, struct cil_list *cons_expr) +{ + struct cil_list_item *i1; + enum cil_flavor op; + size_t len; + + i1 = cons_expr->head; + + op = (enum cil_flavor)(uintptr_t)i1->data; + switch (op) { + case CIL_NOT: + len = 6; /* "(not )" */ + len += cil_cons_expr_len(db, i1->next->data); + break; + case CIL_AND: + len = 7; /* "( and )" */ + len += cil_cons_expr_len(db, i1->next->data); + len += cil_cons_expr_len(db, i1->next->next->data); + break; + case CIL_OR: + len = 6; /* "( or )" */ + len += cil_cons_expr_len(db, i1->next->data); + len += cil_cons_expr_len(db, i1->next->next->data); + break; + default: + len = 2; /* "()" */ + len += __cil_cons_leaf_operand_len(db, i1->next); + len += __cil_cons_leaf_op_len(i1); + len += __cil_cons_leaf_operand_len(db, i1->next->next); + } + + return len; +} + +static char *__cil_userattribute_to_string(struct cil_db *db, struct cil_userattribute *attr, char *new) +{ + ebitmap_node_t *unode; + unsigned int i; + char *str; + size_t len; + + ebitmap_for_each_positive_bit(attr->users, unode, i) { + str = DATUM(db->val_to_user[i])->fqn; + len = strlen(str); + memcpy(new, str, len); + new += len; + *new++ = ' '; + } + + return new; +} + +static char *__cil_cons_leaf_operand_to_string(struct cil_db *db, struct cil_list_item *operand, char *new) +{ + struct cil_list_item *i1; + enum cil_flavor flavor = operand->flavor; + const char *o_str; + size_t o_len; + + if (flavor == CIL_CONS_OPERAND) { + enum cil_flavor o_flavor = (enum cil_flavor)(uintptr_t)operand->data; + switch (o_flavor) { + case CIL_CONS_U1: + o_str = "u1"; + break; + case CIL_CONS_U2: + o_str = "u2"; + break; + case CIL_CONS_U3: + o_str = "u3"; + break; + case CIL_CONS_R1: + o_str = "r1"; + break; + case CIL_CONS_R2: + o_str = "r2"; + break; + case CIL_CONS_R3: + o_str = "r3"; + break; + case CIL_CONS_T1: + o_str = "t1"; + break; + case CIL_CONS_T2: + o_str = "t2"; + break; + case CIL_CONS_T3: + o_str = "t3"; + break; + case CIL_CONS_L1: + o_str = "l1"; + break; + case CIL_CONS_L2: + o_str = "l2"; + break; + case CIL_CONS_H1: + o_str = "h1"; + break; + case CIL_CONS_H2: + o_str = "h2"; + break; + default: + /* Impossible */ + o_str = "??"; + } + strcpy(new, o_str); + new += 2; + } else if (flavor == CIL_DATUM) { + struct cil_tree_node *node = NODE(operand->data); + if (node->flavor == CIL_USERATTRIBUTE) { + *new++ = '{'; + new = __cil_userattribute_to_string(db, operand->data, new); + new--; + *new++ = '}'; + } else { + o_str = DATUM(operand->data)->fqn; + o_len = strlen(o_str); + memcpy(new, o_str, o_len); + new += o_len; + } + } else if (flavor == CIL_LIST) { + *new++ = '{'; + cil_list_for_each(i1, (struct cil_list *)operand->data) { + struct cil_tree_node *node = NODE(operand->data); + if (node->flavor == CIL_USERATTRIBUTE) { + new = __cil_userattribute_to_string(db, operand->data, new); + } else { + o_str = DATUM(operand->data)->fqn; + o_len = strlen(o_str); + memcpy(new, o_str, o_len); + new += o_len; + *new++ = ' '; + } + } + new--; + *new++ = '}'; + } + + return new; +} + +static char *__cil_cons_leaf_op_to_string(struct cil_list_item *op, char *new) +{ + enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data; + const char *op_str; + size_t len; + + switch (flavor) { + case CIL_EQ: + op_str = " == "; + len = 4; + break; + case CIL_NEQ: + op_str = " != "; + len = 4; + break; + case CIL_CONS_DOM: + op_str = " dom "; + len = 5; + break; + case CIL_CONS_DOMBY: + op_str = " domby "; + len = 7; + break; + case CIL_CONS_INCOMP: + op_str = " incomp "; + len = 8; + break; + default: + /* Should be impossible to be here */ + op_str = " ??? "; + len = 5; + } + + strcpy(new, op_str); + new += len; + + return new; +} + +static char *__cil_cons_expr_to_string(struct cil_db *db, struct cil_list *cons_expr, char *new) +{ + struct cil_list_item *i1; + enum cil_flavor op; + + i1 = cons_expr->head; + + op = (enum cil_flavor)(uintptr_t)i1->data; + switch (op) { + case CIL_NOT: + *new++ = '('; + strcpy(new, "not "); + new += 4; + new = __cil_cons_expr_to_string(db, i1->next->data, new); + *new++ = ')'; + break; + case CIL_AND: + *new++ = '('; + new = __cil_cons_expr_to_string(db, i1->next->data, new); + strcpy(new, " and "); + new += 5; + new = __cil_cons_expr_to_string(db, i1->next->next->data, new); + *new++ = ')'; + break; + case CIL_OR: + *new++ = '('; + new = __cil_cons_expr_to_string(db, i1->next->data, new); + strcpy(new, " or "); + new += 4; + new = __cil_cons_expr_to_string(db, i1->next->next->data, new); + *new++ = ')'; + break; + default: + *new++ = '('; + new = __cil_cons_leaf_operand_to_string(db, i1->next, new); + new = __cil_cons_leaf_op_to_string(i1, new); + new = __cil_cons_leaf_operand_to_string(db, i1->next->next, new); + *new++ = ')'; + } + + return new; +} + +static char *cil_cons_expr_to_string(struct cil_db *db, struct cil_list *cons_expr) +{ + char *new, *tail; + size_t len = cil_cons_expr_len(db, cons_expr); + + new = cil_malloc(len+1); + tail = __cil_cons_expr_to_string(db, cons_expr, new); + *tail = '\0'; + + return new; +} + +static void cil_classperms_to_string(struct cil_classperms *classperms, struct cil_list *classperms_strs) +{ + struct cil_list_item *i1; + size_t len = 0; + char *new, *curr; + + len += strlen(DATUM(classperms->class)->fqn) + 1; + cil_list_for_each(i1, classperms->perms) { + len += strlen(DATUM(i1->data)->fqn) + 1; + } + len += 4; /* for "{ " and " }" */ + + new = cil_malloc(len); + curr = new; + + curr[len-1] = '\0'; + + len = strlen(DATUM(classperms->class)->fqn); + memcpy(curr, DATUM(classperms->class)->fqn, len); + curr += len; + *curr++ = ' '; + + *curr++ = '{'; + *curr++ = ' '; + cil_list_for_each(i1, classperms->perms) { + len = strlen(DATUM(i1->data)->fqn); + memcpy(curr, DATUM(i1->data)->fqn, len); + curr += len; + *curr++ = ' '; + } + *curr++ = '}'; + + cil_list_append(classperms_strs, CIL_STRING, new); +} + +static void cil_classperms_to_strings(struct cil_list *classperms, struct cil_list *classperms_strs) +{ + struct cil_list_item *i1; + + cil_list_for_each(i1, classperms) { + if (i1->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = i1->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + cil_classperms_to_string(cp, classperms_strs); + } else { /* MAP */ + struct cil_list_item *i2 = NULL; + cil_list_for_each(i2, cp->perms) { + struct cil_perm *cmp = i2->data; + cil_classperms_to_strings(cmp->classperms, classperms_strs); + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = i1->data; + struct cil_classpermission *cp = cp_set->set; + cil_classperms_to_strings(cp->classperms, classperms_strs); + } + } +} + +static void cil_class_decls_to_policy(FILE *out, struct cil_list *classorder) +{ + struct cil_list_item *i1; + + cil_list_for_each(i1, classorder) { + fprintf(out, "class %s\n", DATUM(i1->data)->fqn); + } +} + +static void cil_sid_decls_to_policy(FILE *out, struct cil_list *sidorder) +{ + struct cil_list_item *i1; + + cil_list_for_each(i1, sidorder) { + fprintf(out, "sid %s\n", DATUM(i1->data)->fqn); + } +} + +static void cil_commons_to_policy(FILE *out, struct cil_list *commons) +{ + struct cil_list_item *i1; + struct cil_class* common; + struct cil_tree_node *node; + struct cil_tree_node *perm; + + cil_list_for_each(i1, commons) { + common = i1->data; + node = NODE(&common->datum); + perm = node->cl_head; + + fprintf(out, "common %s {", common->datum.fqn); + while (perm != NULL) { + fprintf(out, "%s ", DATUM(perm->data)->fqn); + perm = perm->next; + } + fprintf(out, "}\n"); + } +} + +static void cil_classes_to_policy(FILE *out, struct cil_list *classorder) +{ + struct cil_list_item *i1; + struct cil_class *class; + struct cil_tree_node *node; + + cil_list_for_each(i1, classorder) { + class = i1->data; + node = NODE(&class->datum); + + fprintf(out, "class %s", class->datum.fqn); + if (class->common != NULL) { + fprintf(out, " inherits %s", class->common->datum.fqn); + } + if (node->cl_head != NULL) { + struct cil_tree_node *perm = node->cl_head; + fprintf(out, " {"); + while (perm != NULL) { + fprintf(out, " %s", DATUM(perm->data)->fqn); + perm = perm->next; + } + fprintf(out, " }"); + } + fprintf(out, "\n"); + } +} + +static void cil_defaults_to_policy(FILE *out, struct cil_list *defaults, const char *kind) +{ + struct cil_list_item *i1, *i2, *i3; + struct cil_default *def; + struct cil_list *class_list; + + cil_list_for_each(i1, defaults) { + def = i1->data; + fprintf(out, "%s {",kind); + cil_list_for_each(i2, def->class_datums) { + class_list = cil_expand_class(i2->data); + cil_list_for_each(i3, class_list) { + fprintf(out, " %s", DATUM(i3->data)->fqn); + } + cil_list_destroy(&class_list, CIL_FALSE); + } + fprintf(out, " }"); + if (def->object == CIL_DEFAULT_SOURCE) { + fprintf(out," %s",CIL_KEY_SOURCE); + } else if (def->object == CIL_DEFAULT_TARGET) { + fprintf(out," %s",CIL_KEY_TARGET); + } + fprintf(out,";\n"); + } +} + +static void cil_default_ranges_to_policy(FILE *out, struct cil_list *defaults) +{ + struct cil_list_item *i1, *i2, *i3; + struct cil_defaultrange *def; + struct cil_list *class_list; + + cil_list_for_each(i1, defaults) { + def = i1->data; + fprintf(out, "default_range {"); + cil_list_for_each(i2, def->class_datums) { + class_list = cil_expand_class(i2->data); + cil_list_for_each(i3, class_list) { + fprintf(out, " %s", DATUM(i3->data)->fqn); + } + cil_list_destroy(&class_list, CIL_FALSE); + } + fprintf(out, " }"); + + switch (def->object_range) { + case CIL_DEFAULT_SOURCE_LOW: + fprintf(out," %s %s", CIL_KEY_SOURCE, CIL_KEY_LOW); + break; + case CIL_DEFAULT_SOURCE_HIGH: + fprintf(out," %s %s", CIL_KEY_SOURCE, CIL_KEY_HIGH); + break; + case CIL_DEFAULT_SOURCE_LOW_HIGH: + fprintf(out," %s %s", CIL_KEY_SOURCE, CIL_KEY_LOW_HIGH); + break; + case CIL_DEFAULT_TARGET_LOW: + fprintf(out," %s %s", CIL_KEY_TARGET, CIL_KEY_LOW); + break; + case CIL_DEFAULT_TARGET_HIGH: + fprintf(out," %s %s", CIL_KEY_TARGET, CIL_KEY_HIGH); + break; + case CIL_DEFAULT_TARGET_LOW_HIGH: + fprintf(out," %s %s", CIL_KEY_TARGET, CIL_KEY_LOW_HIGH); + break; + case CIL_DEFAULT_GLBLUB: + fprintf(out," %s", CIL_KEY_GLBLUB); + break; + default: + break; + } + fprintf(out,";\n"); + } +} + +static void cil_sensitivities_to_policy(FILE *out, struct cil_list *sensorder, struct cil_list *all_aliases) +{ + struct cil_list_item *i1, *i2; + struct cil_sens *sens; + struct cil_list *aliases = NULL; + struct cil_alias *alias; + struct cil_sens *actual; + int num_aliases; + + cil_list_for_each(i1, sensorder) { + sens = i1->data; + num_aliases = 0; + cil_list_for_each(i2, all_aliases) { + alias = i2->data; + actual = alias->actual; + if (sens == actual) { + if (num_aliases == 0) { + cil_list_init(&aliases, CIL_LIST); + } + cil_list_append(aliases, CIL_SENSALIAS, alias); + num_aliases++; + } + } + fprintf(out, "sensitivity %s", sens->datum.fqn); + if (num_aliases > 0) { + fprintf(out, " alias"); + if (num_aliases > 1) { + fprintf(out, " {"); + } + cil_list_for_each(i2, aliases) { + alias = i2->data; + fprintf(out, " %s", alias->datum.fqn); + } + if (num_aliases > 1) { + fprintf(out, " }"); + } + cil_list_destroy(&aliases, CIL_FALSE); + } + fprintf(out, ";\n"); + } +} + +static void cil_dominance_to_policy(FILE *out, struct cil_list *sensorder) +{ + struct cil_list_item *item; + struct cil_sens *sens; + + fprintf(out, "dominance {"); + cil_list_for_each(item, sensorder) { + sens = item->data; + fprintf(out, " %s", sens->datum.fqn); + } + fprintf(out, " }\n"); +} + +static void cil_categories_to_policy(FILE *out, struct cil_list *catorder, struct cil_list *all_aliases) +{ + struct cil_list_item *i1, *i2; + struct cil_sens *cat; + struct cil_list *aliases = NULL; + struct cil_alias *alias; + struct cil_sens *actual; + int num_aliases; + + cil_list_for_each(i1, catorder) { + cat = i1->data; + num_aliases = 0; + cil_list_for_each(i2, all_aliases) { + alias = i2->data; + actual = alias->actual; + if (cat == actual) { + if (num_aliases == 0) { + cil_list_init(&aliases, CIL_LIST); + } + cil_list_append(aliases, CIL_CATALIAS, alias); + num_aliases++; + } + } + fprintf(out, "category %s",cat->datum.fqn); + if (num_aliases > 0) { + fprintf(out, " alias"); + if (num_aliases > 1) { + fprintf(out, " { "); + } + cil_list_for_each(i2, aliases) { + alias = i2->data; + fprintf(out, " %s", alias->datum.fqn); + } + if (num_aliases > 1) { + fprintf(out, " }"); + } + cil_list_destroy(&aliases, CIL_FALSE); + } + fprintf(out, ";\n"); + } +} + +static void cil_levels_to_policy(FILE *out, struct cil_list *sensorder) +{ + struct cil_list_item *i1, *i2; + struct cil_sens *sens; + + cil_list_for_each(i1, sensorder) { + sens = i1->data; + if (sens->cats_list) { + cil_list_for_each(i2, sens->cats_list) { + fprintf(out, "level %s:",sens->datum.fqn); + cil_cats_to_policy(out, i2->data); + fprintf(out,";\n"); + } + } else { + fprintf(out, "level %s;\n",sens->datum.fqn); + } + } +} + +static void cil_mlsconstrains_to_policy(FILE *out, struct cil_db *db, struct cil_list *mlsconstrains) +{ + struct cil_list_item *i1, *i2; + struct cil_constrain *cons; + struct cil_list *classperms_strs; + char *cp_str; + char *expr_str; + + cil_list_for_each(i1, mlsconstrains) { + cons = i1->data; + cil_list_init(&classperms_strs, CIL_LIST); + cil_classperms_to_strings(cons->classperms, classperms_strs); + expr_str = cil_cons_expr_to_string(db, cons->datum_expr); + cil_list_for_each(i2, classperms_strs) { + cp_str = i2->data; + fprintf(out, "mlsconstrain %s %s;\n", cp_str, expr_str); + free(cp_str); + } + free(expr_str); + cil_list_destroy(&classperms_strs, CIL_FALSE); + } +} + +static void cil_validatetrans_to_policy(FILE *out, struct cil_db *db, struct cil_list *validatetrans, char *kind) +{ + struct cil_list_item *i1, *i2; + struct cil_validatetrans *trans; + struct cil_list *class_list; + struct cil_class *class; + char *expr_str; + + cil_list_for_each(i1, validatetrans) { + trans = i1->data; + class_list = cil_expand_class(trans->class); + expr_str = cil_cons_expr_to_string(db, trans->datum_expr); + cil_list_for_each(i2, class_list) { + class = i2->data; + fprintf(out, "%s %s %s;\n", kind, class->datum.fqn, expr_str); + } + free(expr_str); + cil_list_destroy(&class_list, CIL_FALSE); + } +} + +static void cil_bools_to_policy(FILE *out, struct cil_list *bools) +{ + struct cil_list_item *i1; + struct cil_bool *bool; + const char *value; + + cil_list_for_each(i1, bools) { + bool = i1->data; + value = bool->value ? "true" : "false"; + fprintf(out, "bool %s %s;\n", bool->datum.fqn, value); + } +} + +static void cil_typealiases_to_policy(FILE *out, struct cil_list *types, struct cil_list *all_aliases) +{ + struct cil_list_item *i1, *i2; + struct cil_type *type; + struct cil_list *aliases = NULL; + struct cil_alias *alias; + struct cil_type *actual; + int num_aliases; + + cil_list_for_each(i1, types) { + type = i1->data; + num_aliases = 0; + cil_list_for_each(i2, all_aliases) { + alias = i2->data; + actual = alias->actual; + if (type == actual) { + if (num_aliases == 0) { + cil_list_init(&aliases, CIL_LIST); + } + cil_list_append(aliases, CIL_TYPEALIAS, alias); + num_aliases++; + } + } + if (num_aliases > 0) { + fprintf(out, "typealias %s alias", type->datum.fqn); + if (num_aliases > 1) { + fprintf(out, " {"); + } + cil_list_for_each(i2, aliases) { + alias = i2->data; + fprintf(out, " %s", alias->datum.fqn); + } + if (num_aliases > 1) { + fprintf(out, " }"); + } + fprintf(out, ";\n"); + cil_list_destroy(&aliases, CIL_FALSE); + } + } +} + +static void cil_typebounds_to_policy(FILE *out, struct cil_list *types) +{ + struct cil_list_item *i1; + struct cil_type *child; + struct cil_type *parent; + + cil_list_for_each(i1, types) { + child = i1->data; + if (child->bounds != NULL) { + parent = child->bounds; + fprintf(out, "typebounds %s %s;\n", parent->datum.fqn, child->datum.fqn); + } + } +} + +static void cil_typeattributes_to_policy(FILE *out, struct cil_list *types, struct cil_list *attributes) +{ + struct cil_list_item *i1, *i2; + struct cil_type *type; + struct cil_typeattribute *attribute; + int first = CIL_TRUE; + + cil_list_for_each(i1, types) { + type = i1->data; + cil_list_for_each(i2, attributes) { + attribute = i2->data; + if (!attribute->keep) + continue; + if (ksu_ebitmap_get_bit(attribute->types, type->value)) { + if (first) { + fprintf(out, "typeattribute %s %s", type->datum.fqn, attribute->datum.fqn); + first = CIL_FALSE; + } else { + fprintf(out, ", %s", attribute->datum.fqn); + } + } + } + if (!first) { + fprintf(out, ";\n"); + first = CIL_TRUE; + } + } +} + +static void cil_xperms_to_policy(FILE *out, struct cil_permissionx *permx) +{ + ebitmap_node_t *node; + unsigned int i, first = 0, last = 0; + int need_first = CIL_TRUE, need_last = CIL_TRUE; + const char *kind; + + if (permx->kind == CIL_PERMX_KIND_IOCTL) { + kind = "ioctl"; + } else { + kind = "???"; + } + + fprintf(out, "%s %s {", DATUM(permx->obj)->fqn, kind); + + ebitmap_for_each_positive_bit(permx->perms, node, i) { + if (need_first == CIL_TRUE) { + first = i; + need_first = CIL_FALSE; + } else if (need_last == CIL_TRUE) { + if (i == first+1) { + last = i; + need_last = CIL_FALSE; + } else { + fprintf(out, " 0x%x", first); + first = i; + } + } else if (i == last+1) { + last = i; + } else { + if (last > first+1) { + fprintf(out, " 0x%x-0x%x", first, last); + } else { + fprintf(out, " 0x%x 0x%x", first, last); + } + first = i; + need_last = CIL_TRUE; + } + } + if (need_first == CIL_FALSE) { + if (need_last == CIL_FALSE) { + fprintf(out, " 0x%x-0x%x", first, last); + } else { + fprintf(out, " 0x%x", first); + } + } + fprintf(out," }"); +} + +static void cil_av_rulex_to_policy(FILE *out, struct cil_avrule *rule) +{ + const char *kind; + struct cil_symtab_datum *src, *tgt; + + src = rule->src; + tgt = rule->tgt; + + switch (rule->rule_kind) { + case CIL_AVRULE_ALLOWED: + kind = "allowxperm"; + break; + case CIL_AVRULE_AUDITALLOW: + kind = "auditallowxperm"; + break; + case CIL_AVRULE_DONTAUDIT: + kind = "dontauditxperm"; + break; + case CIL_AVRULE_NEVERALLOW: + kind = "neverallowxperm"; + break; + default: + kind = "???"; + break; + } + + fprintf(out, "%s %s %s : ", kind, src->fqn, tgt->fqn); + cil_xperms_to_policy(out, rule->perms.x.permx); + fprintf(out, ";\n"); +} + +static void cil_av_rule_to_policy(FILE *out, struct cil_avrule *rule) +{ + const char *kind; + struct cil_symtab_datum *src, *tgt; + struct cil_list *classperms_strs; + struct cil_list_item *i1; + + src = rule->src; + tgt = rule->tgt; + + switch (rule->rule_kind) { + case CIL_AVRULE_ALLOWED: + kind = "allow"; + break; + case CIL_AVRULE_AUDITALLOW: + kind = "auditallow"; + break; + case CIL_AVRULE_DONTAUDIT: + kind = "dontaudit"; + break; + case CIL_AVRULE_NEVERALLOW: + kind = "neverallow"; + break; + default: + kind = "???"; + break; + } + + cil_list_init(&classperms_strs, CIL_LIST); + cil_classperms_to_strings(rule->perms.classperms, classperms_strs); + cil_list_for_each(i1, classperms_strs) { + char *cp_str = i1->data; + fprintf(out, "%s %s %s : %s;\n", kind, src->fqn, tgt->fqn, cp_str); + free(cp_str); + } + cil_list_destroy(&classperms_strs, CIL_FALSE); +} + +static void cil_type_rule_to_policy(FILE *out, struct cil_type_rule *rule) +{ + const char *kind; + struct cil_symtab_datum *src, *tgt, *res; + struct cil_list *class_list; + struct cil_list_item *i1; + + src = rule->src; + tgt = rule->tgt; + res = rule->result; + + switch (rule->rule_kind) { + case CIL_TYPE_TRANSITION: + kind = "type_transition"; + break; + case CIL_TYPE_MEMBER: + kind = "type_member"; + break; + case CIL_TYPE_CHANGE: + kind = "type_change"; + break; + default: + kind = "???"; + break; + } + + class_list = cil_expand_class(rule->obj); + cil_list_for_each(i1, class_list) { + fprintf(out, "%s %s %s : %s %s;\n", kind, src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn); + } + cil_list_destroy(&class_list, CIL_FALSE); +} + +static void cil_nametypetransition_to_policy(FILE *out, struct cil_nametypetransition *trans) +{ + struct cil_symtab_datum *src, *tgt, *res; + struct cil_name *name; + struct cil_list *class_list; + struct cil_list_item *i1; + + src = trans->src; + tgt = trans->tgt; + name = trans->name; + res = trans->result; + + class_list = cil_expand_class(trans->obj); + cil_list_for_each(i1, class_list) { + fprintf(out, "type_transition %s %s : %s %s \"%s\";\n", src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn, name->datum.fqn); + } + cil_list_destroy(&class_list, CIL_FALSE); +} + +static void cil_rangetransition_to_policy(FILE *out, struct cil_rangetransition *trans) +{ + struct cil_symtab_datum *src, *exec; + struct cil_list *class_list; + struct cil_list_item *i1; + + src = trans->src; + exec = trans->exec; + + class_list = cil_expand_class(trans->obj); + cil_list_for_each(i1, class_list) { + fprintf(out, "range_transition %s %s : %s ", src->fqn, exec->fqn, DATUM(i1->data)->fqn); + cil_levelrange_to_policy(out, trans->range); + fprintf(out, ";\n"); + } + cil_list_destroy(&class_list, CIL_FALSE); +} + +static void cil_typepermissive_to_policy(FILE *out, struct cil_typepermissive *rule) +{ + fprintf(out, "permissive %s;\n", DATUM(rule->type)->fqn); +} + +struct block_te_rules_extra { + FILE *out; + enum cil_flavor flavor; + uint32_t rule_kind; +}; + +static int __cil_block_te_rules_to_policy_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + struct block_te_rules_extra *args = extra_args; + + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_BOOLEANIF: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_AVRULE: + case CIL_AVRULEX: + if (args->flavor == node->flavor) { + struct cil_avrule *rule = node->data; + if (args->rule_kind == rule->rule_kind) { + if (rule->is_extended) { + cil_av_rulex_to_policy(args->out, rule); + } else { + cil_av_rule_to_policy(args->out, rule); + } + } + } + break; + case CIL_TYPE_RULE: + if (args->flavor == node->flavor) { + struct cil_type_rule *rule = node->data; + if (args->rule_kind == rule->rule_kind) { + cil_type_rule_to_policy(args->out, rule); + } + } + + break; + case CIL_NAMETYPETRANSITION: + if (args->flavor == node->flavor) { + cil_nametypetransition_to_policy(args->out, node->data); + } + break; + case CIL_RANGETRANSITION: + if (args->flavor == node->flavor) { + cil_rangetransition_to_policy(args->out, node->data); + } + + break; + case CIL_TYPEPERMISSIVE: + if (args->flavor == node->flavor) { + cil_typepermissive_to_policy(args->out, node->data); + } + break; + default: + break; + } + + return SEPOL_OK; +} + +static void cil_block_te_rules_to_policy(FILE *out, struct cil_tree_node *start, int mls) +{ + struct block_te_rules_extra args; + + args.out = out; + + args.flavor = CIL_TYPEPERMISSIVE; + args.rule_kind = 0; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + + args.flavor = CIL_AVRULE; + args.rule_kind = CIL_AVRULE_ALLOWED; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_AVRULE_AUDITALLOW; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_AVRULE_DONTAUDIT; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_AVRULE_NEVERALLOW; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + + args.flavor = CIL_AVRULEX; + args.rule_kind = CIL_AVRULE_ALLOWED; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_AVRULE_AUDITALLOW; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_AVRULE_DONTAUDIT; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_AVRULE_NEVERALLOW; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + + args.flavor = CIL_TYPE_RULE; + args.rule_kind = CIL_TYPE_TRANSITION; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_TYPE_MEMBER; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_TYPE_CHANGE; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + args.rule_kind = CIL_AVRULE_TYPE; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + + args.flavor = CIL_NAMETYPETRANSITION; + args.rule_kind = 0; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + + if (mls == CIL_TRUE) { + args.flavor = CIL_RANGETRANSITION; + args.rule_kind = 0; + cil_tree_walk(start, __cil_block_te_rules_to_policy_helper, NULL, NULL, &args); + } +} + +struct te_rules_extra { + FILE *out; + int mls; +}; + +static int __cil_te_rules_to_policy_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + struct te_rules_extra *args = extra_args; + + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_BOOLEANIF: { + struct cil_booleanif *bool = node->data; + struct cil_tree_node *n; + struct cil_condblock *cb; + + fprintf(args->out, "if "); + cil_cond_expr_to_policy(args->out, bool->datum_expr, CIL_TRUE); + fprintf(args->out," {\n"); + n = node->cl_head; + cb = n != NULL ? n->data : NULL; + if (cb && cb->flavor == CIL_CONDTRUE) { + cil_block_te_rules_to_policy(args->out, n, args->mls); + n = n->next; + cb = n != NULL ? n->data : NULL; + } + if (cb && cb->flavor == CIL_CONDFALSE) { + fprintf(args->out,"} else {\n"); + cil_block_te_rules_to_policy(args->out, n, args->mls); + } + fprintf(args->out,"}\n"); + *finished = CIL_TREE_SKIP_HEAD; + break; + } + default: + break; + } + + return SEPOL_OK; +} + +static void cil_te_rules_to_policy(FILE *out, struct cil_tree_node *head, int mls) +{ + struct te_rules_extra args; + + args.out = out; + args.mls = mls; + + cil_block_te_rules_to_policy(out, head, mls); + cil_tree_walk(head, __cil_te_rules_to_policy_helper, NULL, NULL, &args); +} + +static void cil_roles_to_policy(FILE *out, struct cil_list *rules) +{ + struct cil_list_item *i1; + struct cil_role *role; + + cil_list_for_each(i1, rules) { + role = i1->data; + if (strcmp(role->datum.fqn,"object_r") == 0) + continue; + fprintf(out, "role %s;\n", role->datum.fqn); + } +} + +static void cil_role_types_to_policy(FILE *out, struct cil_list *roles, struct cil_list *types) +{ + struct cil_list_item *i1, *i2; + struct cil_role *role; + struct cil_type *type; + int first = CIL_TRUE; + + cil_list_for_each(i1, roles) { + role = i1->data; + if (strcmp(role->datum.fqn,"object_r") == 0) + continue; + if (role->types) { + cil_list_for_each(i2, types) { + type = i2->data; + if (ksu_ebitmap_get_bit(role->types, type->value)) { + if (first) { + fprintf(out, "role %s types { %s", role->datum.fqn, type->datum.fqn); + first = CIL_FALSE; + } else { + fprintf(out, " %s", type->datum.fqn); + } + } + } + if (!first) { + fprintf(out, " }"); + first = CIL_TRUE; + } + fprintf(out, ";\n"); + } + } +} + +static void cil_roleattributes_to_policy(FILE *out, struct cil_list *roles, struct cil_list *attributes) +{ + struct cil_list_item *i1, *i2; + struct cil_role *role; + struct cil_roleattribute *attribute; + int first = CIL_TRUE; + + cil_list_for_each(i1, roles) { + role = i1->data; + if (strcmp(role->datum.fqn,"object_r") == 0) + continue; + cil_list_for_each(i2, attributes) { + attribute = i2->data; + if (ksu_ebitmap_get_bit(attribute->roles, role->value)) { + if (first) { + fprintf(out, "roleattribute %s %s", role->datum.fqn, attribute->datum.fqn); + first = CIL_FALSE; + } else { + fprintf(out, ", %s", attribute->datum.fqn); + } + } + } + if (!first) { + fprintf(out, ";\n"); + first = CIL_TRUE; + } + } +} + +static void cil_roleallows_to_policy(FILE *out, struct cil_list *roleallows) +{ + struct cil_list_item *i1; + struct cil_roleallow *allow; + + cil_list_for_each(i1, roleallows) { + allow = i1->data; + fprintf(out, "allow %s %s;\n", DATUM(allow->src)->fqn, DATUM(allow->tgt)->fqn); + } +} + +static void cil_roletransitions_to_policy(FILE *out, struct cil_list *roletransitions) +{ + struct cil_list_item *i1, *i2; + struct cil_list *class_list; + struct cil_roletransition *trans; + + + cil_list_for_each(i1, roletransitions) { + trans = i1->data; + class_list = cil_expand_class(trans->obj); + cil_list_for_each(i2, class_list) { + fprintf(out, "role_transition %s %s : %s %s;\n", DATUM(trans->src)->fqn, DATUM(trans->tgt)->fqn, DATUM(i2->data)->fqn, DATUM(trans->result)->fqn); + } + cil_list_destroy(&class_list, CIL_FALSE); + } +} + +static void cil_users_to_policy(FILE *out, int mls, struct cil_list *users, struct cil_list *all_roles) +{ + struct cil_list_item *i1, *i2; + struct cil_user *user; + struct cil_list *roles = NULL; + struct cil_role *role; + int num_roles; + + cil_list_for_each(i1, users) { + user = i1->data; + num_roles = 0; + fprintf(out, "user %s",user->datum.fqn); + cil_list_for_each(i2, all_roles) { + role = i2->data; + if (ksu_ebitmap_get_bit(user->roles, role->value)) { + if (num_roles == 0) { + cil_list_init(&roles, CIL_LIST); + } + cil_list_append(roles, CIL_ROLE, role); + num_roles++; + } + } + if (num_roles > 0) { + fprintf(out, " roles"); + if (num_roles > 1) { + fprintf(out, " {"); + } + cil_list_for_each(i2, roles) { + role = i2->data; + fprintf(out, " %s", role->datum.fqn); + } + if (num_roles > 1) { + fprintf(out, " }"); + } + cil_list_destroy(&roles, CIL_FALSE); + } + + if (mls == CIL_TRUE && user->dftlevel != NULL) { + fprintf(out, " level "); + cil_level_to_policy(out, user->dftlevel); + } + + if (mls == CIL_TRUE && user->range != NULL) { + fprintf(out, " range "); + cil_levelrange_to_policy(out, user->range); + } + + fprintf(out,";\n"); + } +} + +static void cil_constrains_to_policy(FILE *out, struct cil_db *db, struct cil_list *constrains) +{ + struct cil_list_item *i1, *i2; + struct cil_constrain *cons; + struct cil_list *classperms_strs; + char *cp_str; + char *expr_str; + + cil_list_for_each(i1, constrains) { + cons = i1->data; + cil_list_init(&classperms_strs, CIL_LIST); + cil_classperms_to_strings(cons->classperms, classperms_strs); + expr_str = cil_cons_expr_to_string(db, cons->datum_expr); + cil_list_for_each(i2, classperms_strs) { + cp_str = i2->data; + fprintf(out, "constrain %s %s;\n",cp_str, expr_str); + free(cp_str); + } + free(expr_str); + cil_list_destroy(&classperms_strs, CIL_FALSE); + } +} + +static void cil_sid_contexts_to_policy(FILE *out, struct cil_list *sids, int mls) +{ + struct cil_list_item *i1; + struct cil_sid *sid; + + cil_list_for_each(i1, sids) { + sid = i1->data; + if (sid->context) { + fprintf(out, "sid %s ", sid->datum.fqn); + cil_context_to_policy(out, sid->context, mls); + fprintf(out,"\n"); + } + } +} + +static void cil_fsuses_to_policy(FILE *out, struct cil_sort *fsuses, int mls) +{ + unsigned i; + struct cil_fsuse *fsuse; + + for (i=0; icount; i++) { + fsuse = fsuses->array[i]; + if (fsuse->type == CIL_FSUSE_XATTR) { + fprintf(out, "fs_use_xattr %s ", fsuse->fs_str); + cil_context_to_policy(out, fsuse->context, mls); + fprintf(out,";\n"); + } + } + + for (i=0; icount; i++) { + fsuse = fsuses->array[i]; + if (fsuse->type == CIL_FSUSE_TASK) { + fprintf(out, "fs_use_task %s ", fsuse->fs_str); + cil_context_to_policy(out, fsuse->context, mls); + fprintf(out,";\n"); + } + } + + for (i=0; icount; i++) { + fsuse = fsuses->array[i]; + if (fsuse->type == CIL_FSUSE_TRANS) { + fprintf(out, "fs_use_trans %s ", fsuse->fs_str); + cil_context_to_policy(out, fsuse->context, mls); + fprintf(out,";\n"); + } + } +} + +static void cil_genfscons_to_policy(FILE *out, struct cil_sort *genfscons, int mls) +{ + unsigned i; + struct cil_genfscon *genfscon; + + for (i=0; icount; i++) { + genfscon = genfscons->array[i]; + fprintf(out, "genfscon %s %s ", genfscon->fs_str, genfscon->path_str); + cil_context_to_policy(out, genfscon->context, mls); + fprintf(out, "\n"); + } +} + +static void cil_ibpkeycons_to_policy(FILE *out, struct cil_sort *ibpkeycons, int mls) +{ + uint32_t i = 0; + + for (i = 0; i < ibpkeycons->count; i++) { + struct cil_ibpkeycon *ibpkeycon = (struct cil_ibpkeycon *)ibpkeycons->array[i]; + + fprintf(out, "ibpkeycon %s ", ibpkeycon->subnet_prefix_str); + fprintf(out, "%d ", ibpkeycon->pkey_low); + fprintf(out, "%d ", ibpkeycon->pkey_high); + cil_context_to_policy(out, ibpkeycon->context, mls); + fprintf(out, "\n"); + } +} + +static void cil_ibendportcons_to_policy(FILE *out, struct cil_sort *ibendportcons, int mls) +{ + uint32_t i; + + for (i = 0; i < ibendportcons->count; i++) { + struct cil_ibendportcon *ibendportcon = (struct cil_ibendportcon *)ibendportcons->array[i]; + + fprintf(out, "ibendportcon %s ", ibendportcon->dev_name_str); + fprintf(out, "%u ", ibendportcon->port); + cil_context_to_policy(out, ibendportcon->context, mls); + fprintf(out, "\n"); + } +} + +static void cil_portcons_to_policy(FILE *out, struct cil_sort *portcons, int mls) +{ + unsigned i; + struct cil_portcon *portcon; + + for (i=0; icount; i++) { + portcon = portcons->array[i]; + fprintf(out, "portcon "); + if (portcon->proto == CIL_PROTOCOL_UDP) { + fprintf(out, "udp "); + } else if (portcon->proto == CIL_PROTOCOL_TCP) { + fprintf(out, "tcp "); + } else if (portcon->proto == CIL_PROTOCOL_DCCP) { + fprintf(out, "dccp "); + } else if (portcon->proto == CIL_PROTOCOL_SCTP) { + fprintf(out, "sctp "); + } + if (portcon->port_low == portcon->port_high) { + fprintf(out, "%d ", portcon->port_low); + } else { + fprintf(out, "%d-%d ", portcon->port_low, portcon->port_high); + } + cil_context_to_policy(out, portcon->context, mls); + fprintf(out, "\n"); + } +} + +static void cil_netifcons_to_policy(FILE *out, struct cil_sort *netifcons, int mls) +{ + unsigned i; + struct cil_netifcon *netifcon; + + for (i=0; icount; i++) { + netifcon = netifcons->array[i]; + fprintf(out, "netifcon %s ", netifcon->interface_str); + cil_context_to_policy(out, netifcon->if_context, mls); + fprintf(out, " "); + cil_context_to_policy(out, netifcon->packet_context, mls); + fprintf(out, "\n"); + } +} + +static void cil_nodecons_to_policy(FILE *out, struct cil_sort *nodecons, int mls) +{ + unsigned i; + struct cil_nodecon *nodecon; + char *addr, *mask; + + for (i=0; icount; i++) { + nodecon = nodecons->array[i]; + fprintf(out, "nodecon "); + + if (nodecon->addr->family == AF_INET) { + errno = 0; + addr = cil_malloc(INET_ADDRSTRLEN); + inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v4, addr, INET_ADDRSTRLEN); + if (errno == 0) { + fprintf(out, "%s ",addr); + } else { + fprintf(out, "[INVALID] "); + } + free(addr); + + errno = 0; + mask = cil_malloc(INET_ADDRSTRLEN); + inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v4, mask, INET_ADDRSTRLEN); + if (errno == 0) { + fprintf(out, "%s ",mask); + } else { + fprintf(out, "[INVALID] "); + } + free(mask); + } else { + errno = 0; + addr = cil_malloc(INET6_ADDRSTRLEN); + inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v6, addr, INET6_ADDRSTRLEN); + if (errno == 0) { + fprintf(out, "%s ",addr); + } else { + fprintf(out, "[INVALID] "); + } + free(addr); + + errno = 0; + mask = cil_malloc(INET6_ADDRSTRLEN); + inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v6, mask, INET6_ADDRSTRLEN); + if (errno == 0) { + fprintf(out, "%s ",mask); + } else { + fprintf(out, "[INVALID] "); + } + free(mask); + } + + cil_context_to_policy(out, nodecon->context, mls); + fprintf(out, "\n"); + } +} + +static void cil_pirqcons_to_policy(FILE *out, struct cil_sort *pirqcons, int mls) +{ + unsigned i; + struct cil_pirqcon *pirqcon; + + for (i = 0; icount; i++) { + pirqcon = pirqcons->array[i]; + fprintf(out, "pirqcon %d ", pirqcon->pirq); + cil_context_to_policy(out, pirqcon->context, mls); + fprintf(out, ";\n"); + } +} + +static void cil_iomemcons_to_policy(FILE *out, struct cil_sort *iomemcons, int mls) +{ + unsigned i; + struct cil_iomemcon *iomemcon; + + for (i = 0; icount; i++) { + iomemcon = iomemcons->array[i]; + if (iomemcon->iomem_low == iomemcon->iomem_high) { + fprintf(out, "iomemcon %"PRIx64" ", iomemcon->iomem_low); + } else { + fprintf(out, "iomemcon %"PRIx64"-%"PRIx64" ", iomemcon->iomem_low, iomemcon->iomem_high); + } + cil_context_to_policy(out, iomemcon->context, mls); + fprintf(out, ";\n"); + } +} + +static void cil_ioportcons_to_policy(FILE *out, struct cil_sort *ioportcons, int mls) +{ + unsigned i; + struct cil_ioportcon *ioportcon; + + for (i = 0; i < ioportcons->count; i++) { + ioportcon = ioportcons->array[i]; + fprintf(out, "ioportcon 0x%x-0x%x ", ioportcon->ioport_low, ioportcon->ioport_high); + cil_context_to_policy(out, ioportcon->context, mls); + fprintf(out, ";\n"); + } +} + +static void cil_pcidevicecons_to_policy(FILE *out, struct cil_sort *pcidevicecons, int mls) +{ + unsigned i; + struct cil_pcidevicecon *pcidevicecon; + + for (i = 0; i < pcidevicecons->count; i++) { + pcidevicecon = pcidevicecons->array[i]; + fprintf(out, "pcidevicecon 0x%x ", pcidevicecon->dev); + cil_context_to_policy(out, pcidevicecon->context, mls); + fprintf(out, ";\n"); + } +} + +static void cil_devicetreecons_to_policy(FILE *out, struct cil_sort *devicetreecons, int mls) +{ + unsigned i; + struct cil_devicetreecon *devicetreecon; + + for (i = 0; i < devicetreecons->count; i++) { + devicetreecon = devicetreecons->array[i]; + fprintf(out, "devicetreecon %s ", devicetreecon->path); + cil_context_to_policy(out, devicetreecon->context, mls); + fprintf(out, ";\n"); + } +} + +void cil_gen_policy(FILE *out, struct cil_db *db) +{ + unsigned i; + struct cil_tree_node *head = db->ast->root; + struct cil_list *lists[CIL_LIST_NUM_LISTS]; + + for (i=0; iclassorder); + + cil_sid_decls_to_policy(out, db->sidorder); + + cil_commons_to_policy(out, lists[CIL_LIST_COMMON]); + cil_classes_to_policy(out, db->classorder); + + cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_USER], "default_user"); + cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_ROLE], "default_role"); + cil_defaults_to_policy(out, lists[CIL_LIST_DEFAULT_TYPE], "default_type"); + + if (db->mls == CIL_TRUE) { + cil_default_ranges_to_policy(out, lists[CIL_LIST_DEFAULT_RANGE]); + cil_sensitivities_to_policy(out, db->sensitivityorder, lists[CIL_LIST_SENSALIAS]); + cil_dominance_to_policy(out, db->sensitivityorder); + cil_categories_to_policy(out, db->catorder, lists[CIL_LIST_CATALIAS]); + cil_levels_to_policy(out, db->sensitivityorder); + cil_mlsconstrains_to_policy(out, db, lists[CIL_LIST_MLSCONSTRAIN]); + cil_validatetrans_to_policy(out, db, lists[CIL_LIST_MLSVALIDATETRANS], CIL_KEY_MLSVALIDATETRANS); + } + + cil_simple_rules_to_policy(out, lists[CIL_LIST_POLICYCAP], CIL_KEY_POLICYCAP); + + cil_simple_rules_to_policy(out, lists[CIL_LIST_TYPEATTRIBUTE], "attribute"); + cil_simple_rules_to_policy(out, lists[CIL_LIST_ROLEATTRIBUTE], "attribute_role"); + + cil_bools_to_policy(out, lists[CIL_LIST_BOOL]); + + cil_simple_rules_to_policy(out, lists[CIL_LIST_TYPE], "type"); + cil_typealiases_to_policy(out, lists[CIL_LIST_TYPE], lists[CIL_LIST_TYPEALIAS]); + cil_typebounds_to_policy(out, lists[CIL_LIST_TYPE]); + cil_typeattributes_to_policy(out, lists[CIL_LIST_TYPE], lists[CIL_LIST_TYPEATTRIBUTE]); + cil_te_rules_to_policy(out, head, db->mls); + + cil_roles_to_policy(out, lists[CIL_LIST_ROLE]); + cil_role_types_to_policy(out, lists[CIL_LIST_ROLE], lists[CIL_LIST_TYPE]); + cil_roleattributes_to_policy(out, lists[CIL_LIST_ROLE], lists[CIL_LIST_ROLEATTRIBUTE]); + cil_roleallows_to_policy(out, lists[CIL_LIST_ROLEALLOW]); + cil_roletransitions_to_policy(out, lists[CIL_LIST_ROLETRANSITION]); + + cil_users_to_policy(out, db->mls, lists[CIL_LIST_USER], lists[CIL_LIST_ROLE]); + + cil_constrains_to_policy(out, db, lists[CIL_LIST_CONSTRAINT]); + cil_validatetrans_to_policy(out, db, lists[CIL_LIST_VALIDATETRANS], CIL_KEY_VALIDATETRANS); + + cil_sid_contexts_to_policy(out, db->sidorder, db->mls); + cil_fsuses_to_policy(out, db->fsuse, db->mls); + cil_genfscons_to_policy(out, db->genfscon, db->mls); + cil_portcons_to_policy(out, db->portcon, db->mls); + cil_netifcons_to_policy(out, db->netifcon, db->mls); + cil_ibpkeycons_to_policy(out, db->ibpkeycon, db->mls); + cil_ibendportcons_to_policy(out, db->ibendportcon, db->mls); + cil_nodecons_to_policy(out, db->nodecon, db->mls); + cil_pirqcons_to_policy(out, db->pirqcon, db->mls); + cil_iomemcons_to_policy(out, db->iomemcon, db->mls); + cil_ioportcons_to_policy(out, db->ioportcon, db->mls); + cil_pcidevicecons_to_policy(out, db->pcidevicecon, db->mls); + cil_devicetreecons_to_policy(out, db->devicetreecon, db->mls); + + for (i=0; i +#include +#include +#include +#include +#include + +#include +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_post.h" +#include "cil_policy.h" +#include "cil_verify.h" +#include "cil_symtab.h" + +#define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/src/module_to_cil.c */ +#define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/src/module_to_cil.c */ + +struct fc_data { + unsigned int meta; + size_t stem_len; + size_t str_len; +}; + +static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db); +static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db); + +static int cats_compare(struct cil_cats *a, struct cil_cats *b) +{ + struct cil_list_item *i, *j; + int rc; + + if (a == b) return 0; + if (!a) return -1; + if (!b) return 1; + + /* Expects cat expression to have been evaluated */ + cil_list_for_each(i, a->datum_expr) { + cil_list_for_each(j, b->datum_expr) { + rc = strcmp(DATUM(i->data)->fqn, DATUM(j->data)->fqn); + if (!rc) return rc; + } + } + return 0; +} + +static int level_compare(struct cil_level *a, struct cil_level *b) +{ + int rc; + + if (a == b) return 0; + if (!a) return -1; + if (!b) return 1; + + if (a->sens != b->sens) { + rc = strcmp(DATUM(a->sens)->fqn, DATUM(b->sens)->fqn); + if (rc != 0) return rc; + } + if (a->cats != b->cats) { + return cats_compare(a->cats, b->cats); + } + return 0; +} + +static int range_compare(struct cil_levelrange *a, struct cil_levelrange *b) +{ + int rc; + + if (a == b) return 0; + if (!a) return -1; + if (!b) return 1; + + if (a->low != b->low) { + rc = level_compare(a->low, b->low); + if (rc != 0) return rc; + } + if (a->high != b->high) { + return level_compare(a->high, b->high); + } + return 0; +} + +static int context_compare(struct cil_context *a, struct cil_context *b) +{ + int rc; + + if (a->user != b->user) { + rc = strcmp(DATUM(a->user)->fqn, DATUM(b->user)->fqn); + if (rc != 0) return rc; + } + if (a->role != b->role) { + rc = strcmp(DATUM(a->role)->fqn, DATUM(b->role)->fqn); + if (rc != 0) return rc; + } + if (a->type != b->type) { + rc = strcmp(DATUM(a->type)->fqn, DATUM(b->type)->fqn); + if (rc != 0) return rc; + } + if (a->range != b->range) { + return range_compare(a->range, b->range); + } + return 0; +} + +static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor) +{ + struct cil_list_item *curr; + + cil_list_for_each(curr, list) { + switch (curr->flavor) { + case CIL_LIST: + return CIL_FALSE; + break; + case CIL_OP: + return CIL_FALSE; + break; + default: + if (flavor == CIL_CAT) { + struct cil_symtab_datum *d = curr->data; + struct cil_tree_node *n = d->nodes->head->data; + if (n->flavor == CIL_CATSET) { + return CIL_FALSE; + } + } + break; + } + } + return CIL_TRUE; +} + +static void cil_post_fc_fill_data(struct fc_data *fc, const char *path) +{ + size_t c = 0; + fc->meta = 0; + fc->stem_len = 0; + fc->str_len = 0; + + while (path[c] != '\0') { + switch (path[c]) { + case '.': + case '^': + case '$': + case '?': + case '*': + case '+': + case '|': + case '[': + case '(': + case '{': + fc->meta = 1; + break; + case '\\': + c++; + if (path[c] == '\0') { + if (!fc->meta) { + fc->stem_len++; + } + fc->str_len++; + return; + } + /* FALLTHRU */ + default: + if (!fc->meta) { + fc->stem_len++; + } + break; + } + fc->str_len++; + c++; + } +} + +int cil_post_filecon_compare(const void *a, const void *b) +{ + int rc = 0; + struct cil_filecon *a_filecon = *(struct cil_filecon**)a; + struct cil_filecon *b_filecon = *(struct cil_filecon**)b; + struct fc_data *a_data = cil_malloc(sizeof(*a_data)); + struct fc_data *b_data = cil_malloc(sizeof(*b_data)); + char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1); + char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1); + a_path[0] = '\0'; + b_path[0] = '\0'; + strcat(a_path, a_filecon->path_str); + strcat(b_path, b_filecon->path_str); + cil_post_fc_fill_data(a_data, a_path); + cil_post_fc_fill_data(b_data, b_path); + if (a_data->meta && !b_data->meta) { + rc = -1; + } else if (b_data->meta && !a_data->meta) { + rc = 1; + } else if (a_data->stem_len < b_data->stem_len) { + rc = -1; + } else if (b_data->stem_len < a_data->stem_len) { + rc = 1; + } else if (a_data->str_len < b_data->str_len) { + rc = -1; + } else if (b_data->str_len < a_data->str_len) { + rc = 1; + } else if (a_filecon->type < b_filecon->type) { + rc = -1; + } else if (b_filecon->type < a_filecon->type) { + rc = 1; + } else { + rc = strcmp(a_filecon->path_str, b_filecon->path_str); + } + + free(a_path); + free(b_path); + free(a_data); + free(b_data); + + return rc; +} + +int cil_post_ibpkeycon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_ibpkeycon *aibpkeycon = *(struct cil_ibpkeycon **)a; + struct cil_ibpkeycon *bibpkeycon = *(struct cil_ibpkeycon **)b; + + rc = strcmp(aibpkeycon->subnet_prefix_str, bibpkeycon->subnet_prefix_str); + if (rc) + return rc; + + rc = (aibpkeycon->pkey_high - aibpkeycon->pkey_low) + - (bibpkeycon->pkey_high - bibpkeycon->pkey_low); + if (rc == 0) { + if (aibpkeycon->pkey_low < bibpkeycon->pkey_low) + rc = -1; + else if (bibpkeycon->pkey_low < aibpkeycon->pkey_low) + rc = 1; + } + + return rc; +} + +int cil_post_portcon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_portcon *aportcon = *(struct cil_portcon**)a; + struct cil_portcon *bportcon = *(struct cil_portcon**)b; + + rc = (aportcon->port_high - aportcon->port_low) + - (bportcon->port_high - bportcon->port_low); + if (rc == 0) { + if (aportcon->port_low < bportcon->port_low) { + rc = -1; + } else if (bportcon->port_low < aportcon->port_low) { + rc = 1; + } else if (aportcon->proto < bportcon->proto) { + rc = -1; + } else if (aportcon->proto > bportcon->proto) { + rc = 1; + } + } + + return rc; +} + +int cil_post_genfscon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_genfscon *agenfscon = *(struct cil_genfscon**)a; + struct cil_genfscon *bgenfscon = *(struct cil_genfscon**)b; + + rc = strcmp(agenfscon->fs_str, bgenfscon->fs_str); + if (rc == 0) { + rc = strcmp(agenfscon->path_str, bgenfscon->path_str); + } + + return rc; +} + +int cil_post_netifcon_compare(const void *a, const void *b) +{ + struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a; + struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b; + + return strcmp(anetifcon->interface_str, bnetifcon->interface_str); +} + +int cil_post_ibendportcon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + + struct cil_ibendportcon *aibendportcon = *(struct cil_ibendportcon **)a; + struct cil_ibendportcon *bibendportcon = *(struct cil_ibendportcon **)b; + + rc = strcmp(aibendportcon->dev_name_str, bibendportcon->dev_name_str); + if (rc) + return rc; + + if (aibendportcon->port < bibendportcon->port) + return -1; + else if (bibendportcon->port < aibendportcon->port) + return 1; + + return rc; +} + +int cil_post_nodecon_compare(const void *a, const void *b) +{ + struct cil_nodecon *anodecon; + struct cil_nodecon *bnodecon; + anodecon = *(struct cil_nodecon**)a; + bnodecon = *(struct cil_nodecon**)b; + + /* sort ipv4 before ipv6 */ + if (anodecon->addr->family != bnodecon->addr->family) { + if (anodecon->addr->family == AF_INET) { + return -1; + } else { + return 1; + } + } + + /* most specific netmask goes first, then order by ip addr */ + if (anodecon->addr->family == AF_INET) { + int rc = memcmp(&anodecon->mask->ip.v4, &bnodecon->mask->ip.v4, sizeof(anodecon->mask->ip.v4)); + if (rc != 0) { + return -1 * rc; + } + return memcmp(&anodecon->addr->ip.v4, &bnodecon->addr->ip.v4, sizeof(anodecon->addr->ip.v4)); + } else { + int rc = memcmp(&anodecon->mask->ip.v6, &bnodecon->mask->ip.v6, sizeof(anodecon->mask->ip.v6)); + if (rc != 0) { + return -1 * rc; + } + return memcmp(&anodecon->addr->ip.v6, &bnodecon->addr->ip.v6, sizeof(anodecon->addr->ip.v6)); + } +} + +static int cil_post_pirqcon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_pirqcon *apirqcon = *(struct cil_pirqcon**)a; + struct cil_pirqcon *bpirqcon = *(struct cil_pirqcon**)b; + + if (apirqcon->pirq < bpirqcon->pirq) { + rc = -1; + } else if (bpirqcon->pirq < apirqcon->pirq) { + rc = 1; + } else { + rc = 0; + } + + return rc; +} + +static int cil_post_iomemcon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_iomemcon *aiomemcon = *(struct cil_iomemcon**)a; + struct cil_iomemcon *biomemcon = *(struct cil_iomemcon**)b; + + rc = (aiomemcon->iomem_high - aiomemcon->iomem_low) + - (biomemcon->iomem_high - biomemcon->iomem_low); + if (rc == 0) { + if (aiomemcon->iomem_low < biomemcon->iomem_low) { + rc = -1; + } else if (biomemcon->iomem_low < aiomemcon->iomem_low) { + rc = 1; + } + } + + return rc; +} + +static int cil_post_ioportcon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_ioportcon *aioportcon = *(struct cil_ioportcon**)a; + struct cil_ioportcon *bioportcon = *(struct cil_ioportcon**)b; + + rc = (aioportcon->ioport_high - aioportcon->ioport_low) + - (bioportcon->ioport_high - bioportcon->ioport_low); + if (rc == 0) { + if (aioportcon->ioport_low < bioportcon->ioport_low) { + rc = -1; + } else if (bioportcon->ioport_low < aioportcon->ioport_low) { + rc = 1; + } + } + + return rc; +} + +static int cil_post_pcidevicecon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_pcidevicecon *apcidevicecon = *(struct cil_pcidevicecon**)a; + struct cil_pcidevicecon *bpcidevicecon = *(struct cil_pcidevicecon**)b; + + if (apcidevicecon->dev < bpcidevicecon->dev) { + rc = -1; + } else if (bpcidevicecon->dev < apcidevicecon->dev) { + rc = 1; + } else { + rc = 0; + } + + return rc; +} + +static int cil_post_devicetreecon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a; + struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b; + + rc = strcmp(adevicetreecon->path, bdevicetreecon->path); + + return rc; +} + +int cil_post_fsuse_compare(const void *a, const void *b) +{ + int rc; + struct cil_fsuse *afsuse; + struct cil_fsuse *bfsuse; + afsuse = *(struct cil_fsuse**)a; + bfsuse = *(struct cil_fsuse**)b; + if (afsuse->type < bfsuse->type) { + rc = -1; + } else if (bfsuse->type < afsuse->type) { + rc = 1; + } else { + rc = strcmp(afsuse->fs_str, bfsuse->fs_str); + } + return rc; +} + +static int cil_post_filecon_context_compare(const void *a, const void *b) +{ + struct cil_filecon *a_filecon = *(struct cil_filecon**)a; + struct cil_filecon *b_filecon = *(struct cil_filecon**)b; + return context_compare(a_filecon->context, b_filecon->context); +} + +static int cil_post_ibpkeycon_context_compare(const void *a, const void *b) +{ + struct cil_ibpkeycon *a_ibpkeycon = *(struct cil_ibpkeycon **)a; + struct cil_ibpkeycon *b_ibpkeycon = *(struct cil_ibpkeycon **)b; + return context_compare(a_ibpkeycon->context, b_ibpkeycon->context); +} + +static int cil_post_portcon_context_compare(const void *a, const void *b) +{ + struct cil_portcon *a_portcon = *(struct cil_portcon**)a; + struct cil_portcon *b_portcon = *(struct cil_portcon**)b; + return context_compare(a_portcon->context, b_portcon->context); +} + +static int cil_post_genfscon_context_compare(const void *a, const void *b) +{ + struct cil_genfscon *a_genfscon = *(struct cil_genfscon**)a; + struct cil_genfscon *b_genfscon = *(struct cil_genfscon**)b; + return context_compare(a_genfscon->context, b_genfscon->context); +} + +static int cil_post_netifcon_context_compare(const void *a, const void *b) +{ + int rc; + struct cil_netifcon *a_netifcon = *(struct cil_netifcon**)a; + struct cil_netifcon *b_netifcon = *(struct cil_netifcon**)b; + rc = context_compare(a_netifcon->if_context, b_netifcon->if_context); + if (rc != 0) { + return rc; + } + return context_compare(a_netifcon->packet_context, b_netifcon->packet_context); +} + +static int cil_post_ibendportcon_context_compare(const void *a, const void *b) +{ + struct cil_ibendportcon *a_ibendportcon = *(struct cil_ibendportcon **)a; + struct cil_ibendportcon *b_ibendportcon = *(struct cil_ibendportcon **)b; + return context_compare(a_ibendportcon->context, b_ibendportcon->context); +} + +static int cil_post_nodecon_context_compare(const void *a, const void *b) +{ + struct cil_nodecon *a_nodecon = *(struct cil_nodecon **)a; + struct cil_nodecon *b_nodecon = *(struct cil_nodecon **)b; + return context_compare(a_nodecon->context, b_nodecon->context); +} + +static int cil_post_pirqcon_context_compare(const void *a, const void *b) +{ + struct cil_pirqcon *a_pirqcon = *(struct cil_pirqcon**)a; + struct cil_pirqcon *b_pirqcon = *(struct cil_pirqcon**)b; + return context_compare(a_pirqcon->context, b_pirqcon->context); +} + +static int cil_post_iomemcon_context_compare(const void *a, const void *b) +{ + struct cil_iomemcon *a_iomemcon = *(struct cil_iomemcon**)a; + struct cil_iomemcon *b_iomemcon = *(struct cil_iomemcon**)b; + return context_compare(a_iomemcon->context, b_iomemcon->context); +} + +static int cil_post_ioportcon_context_compare(const void *a, const void *b) +{ + struct cil_ioportcon *a_ioportcon = *(struct cil_ioportcon**)a; + struct cil_ioportcon *b_ioportcon = *(struct cil_ioportcon**)b; + return context_compare(a_ioportcon->context, b_ioportcon->context); +} + +static int cil_post_pcidevicecon_context_compare(const void *a, const void *b) +{ + struct cil_pcidevicecon *a_pcidevicecon = *(struct cil_pcidevicecon**)a; + struct cil_pcidevicecon *b_pcidevicecon = *(struct cil_pcidevicecon**)b; + return context_compare(a_pcidevicecon->context, b_pcidevicecon->context); +} + +static int cil_post_devicetreecon_context_compare(const void *a, const void *b) +{ + struct cil_devicetreecon *a_devicetreecon = *(struct cil_devicetreecon**)a; + struct cil_devicetreecon *b_devicetreecon = *(struct cil_devicetreecon**)b; + return context_compare(a_devicetreecon->context, b_devicetreecon->context); +} + +static int cil_post_fsuse_context_compare(const void *a, const void *b) +{ + struct cil_fsuse *a_fsuse = *(struct cil_fsuse**)a; + struct cil_fsuse *b_fsuse = *(struct cil_fsuse**)b; + return context_compare(a_fsuse->context, b_fsuse->context); +} + +static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + struct cil_db *db = extra_args; + + switch(node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_CLASS: { + struct cil_class *class = node->data; + if (class->datum.nodes->head->data == node) { + // Multiple nodes can point to the same datum. Only count once. + db->num_classes++; + } + break; + } + case CIL_TYPE: { + struct cil_type *type = node->data; + if (type->datum.nodes->head->data == node) { + // Multiple nodes can point to the same datum. Only count once. + type->value = db->num_types; + db->num_types++; + db->num_types_and_attrs++; + } + break; + } + case CIL_TYPEATTRIBUTE: { + struct cil_typeattribute *attr = node->data; + if (attr->datum.nodes->head->data == node) { + // Multiple nodes can point to the same datum. Only count once. + db->num_types_and_attrs++; + } + break; + } + + case CIL_ROLE: { + struct cil_role *role = node->data; + if (role->datum.nodes->head->data == node) { + // Multiple nodes can point to the same datum. Only count once. + role->value = db->num_roles; + db->num_roles++; + } + break; + } + case CIL_USER: { + struct cil_user *user = node->data; + if (user->datum.nodes->head->data == node) { + // multiple AST nodes can point to the same cil_user data (like if + // copied from a macro). This check ensures we only count the + // duplicates once + user->value = db->num_users; + db->num_users++; + } + break; + } + case CIL_NETIFCON: + db->netifcon->count++; + break; + case CIL_GENFSCON: + db->genfscon->count++; + break; + case CIL_FILECON: + db->filecon->count++; + break; + case CIL_NODECON: + db->nodecon->count++; + break; + case CIL_IBPKEYCON: + db->ibpkeycon->count++; + break; + case CIL_IBENDPORTCON: + db->ibendportcon->count++; + break; + case CIL_PORTCON: + db->portcon->count++; + break; + case CIL_PIRQCON: + db->pirqcon->count++; + break; + case CIL_IOMEMCON: + db->iomemcon->count++; + break; + case CIL_IOPORTCON: + db->ioportcon->count++; + break; + case CIL_PCIDEVICECON: + db->pcidevicecon->count++; + break; + case CIL_DEVICETREECON: + db->devicetreecon->count++; + break; + case CIL_FSUSE: + db->fsuse->count++; + break; + default: + break; + } + + return SEPOL_OK; +} + +static int __cil_post_db_array_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + struct cil_db *db = extra_args; + + switch(node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_TYPE: { + struct cil_type *type = node->data; + if (db->val_to_type == NULL) { + db->val_to_type = cil_malloc(sizeof(*db->val_to_type) * db->num_types); + } + db->val_to_type[type->value] = type; + break; + } + case CIL_ROLE: { + struct cil_role *role = node->data; + if (db->val_to_role == NULL) { + db->val_to_role = cil_malloc(sizeof(*db->val_to_role) * db->num_roles); + } + db->val_to_role[role->value] = role; + break; + } + case CIL_USER: { + struct cil_user *user= node->data; + if (db->val_to_user == NULL) { + db->val_to_user = cil_malloc(sizeof(*db->val_to_user) * db->num_users); + } + db->val_to_user[user->value] = user; + break; + } + case CIL_USERPREFIX: { + cil_list_append(db->userprefixes, CIL_USERPREFIX, node->data); + break; + } + case CIL_SELINUXUSER: { + cil_list_prepend(db->selinuxusers, CIL_SELINUXUSER, node->data); + break; + } + case CIL_SELINUXUSERDEFAULT: { + cil_list_append(db->selinuxusers, CIL_SELINUXUSERDEFAULT, node->data); + break; + } + case CIL_NETIFCON: { + struct cil_sort *sort = db->netifcon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_IBENDPORTCON: { + struct cil_sort *sort = db->ibendportcon; + uint32_t count = sort->count; + uint32_t i = sort->index; + + if (!sort->array) + sort->array = cil_malloc(sizeof(*sort->array) * count); + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_FSUSE: { + struct cil_sort *sort = db->fsuse; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_GENFSCON: { + struct cil_sort *sort = db->genfscon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_FILECON: { + struct cil_sort *sort = db->filecon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_NODECON: { + struct cil_sort *sort = db->nodecon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_IBPKEYCON: { + struct cil_sort *sort = db->ibpkeycon; + uint32_t count = sort->count; + uint32_t i = sort->index; + + if (!sort->array) + sort->array = cil_malloc(sizeof(*sort->array) * count); + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_PORTCON: { + struct cil_sort *sort = db->portcon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_PIRQCON: { + struct cil_sort *sort = db->pirqcon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_IOMEMCON: { + struct cil_sort *sort = db->iomemcon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_IOPORTCON: { + struct cil_sort *sort = db->ioportcon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_PCIDEVICECON: { + struct cil_sort *sort = db->pcidevicecon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + case CIL_DEVICETREECON: { + struct cil_sort *sort = db->devicetreecon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } + default: + break; + } + + return SEPOL_OK; +} + +static int __evaluate_type_expression(struct cil_typeattribute *attr, struct cil_db *db) +{ + int rc; + + attr->types = cil_malloc(sizeof(*attr->types)); + rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->types, db->num_types, db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to expand type attribute to bitmap\n"); + ksu_ebitmap_destroy(attr->types); + free(attr->types); + attr->types = NULL; + } + return rc; +} + +static int __cil_type_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *node = datum->nodes->head->data; + + ebitmap_init(bitmap); + + if (node->flavor == CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; + if (attr->types == NULL) { + rc = __evaluate_type_expression(attr, db); + if (rc != SEPOL_OK) goto exit; + } + ebitmap_union(bitmap, attr->types); + } else if (node->flavor == CIL_TYPEALIAS) { + struct cil_alias *alias = (struct cil_alias *)datum; + struct cil_type *type = alias->actual; + if (ksu_ebitmap_set_bit(bitmap, type->value, 1)) { + cil_log(CIL_ERR, "Failed to set type bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } else { + struct cil_type *type = (struct cil_type *)datum; + if (ksu_ebitmap_set_bit(bitmap, type->value, 1)) { + cil_log(CIL_ERR, "Failed to set type bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __evaluate_user_expression(struct cil_userattribute *attr, struct cil_db *db) +{ + int rc; + + attr->users = cil_malloc(sizeof(*attr->users)); + rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->users, db->num_users, db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to expand user attribute to bitmap\n"); + ksu_ebitmap_destroy(attr->users); + free(attr->users); + attr->users = NULL; + } + return rc; +} + +static int __cil_user_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *node = datum->nodes->head->data; + struct cil_userattribute *attr = NULL; + struct cil_user *user = NULL; + + ebitmap_init(bitmap); + + if (node->flavor == CIL_USERATTRIBUTE) { + attr = (struct cil_userattribute *)datum; + if (attr->users == NULL) { + rc = __evaluate_user_expression(attr, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + ebitmap_union(bitmap, attr->users); + } else { + user = (struct cil_user *)datum; + if (ksu_ebitmap_set_bit(bitmap, user->value, 1)) { + cil_log(CIL_ERR, "Failed to set user bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __evaluate_role_expression(struct cil_roleattribute *attr, struct cil_db *db) +{ + int rc; + + attr->roles = cil_malloc(sizeof(*attr->roles)); + rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->roles, db->num_roles, db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to expand role attribute to bitmap\n"); + ksu_ebitmap_destroy(attr->roles); + free(attr->roles); + attr->roles = NULL; + } + return rc; +} + +static int __cil_role_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *node = datum->nodes->head->data; + + ebitmap_init(bitmap); + + if (node->flavor == CIL_ROLEATTRIBUTE) { + struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; + if (attr->roles == NULL) { + rc = __evaluate_role_expression(attr, db); + if (rc != SEPOL_OK) goto exit; + } + ebitmap_union(bitmap, attr->roles); + } else { + struct cil_role *role = (struct cil_role *)datum; + if (ksu_ebitmap_set_bit(bitmap, role->value, 1)) { + cil_log(CIL_ERR, "Failed to set role bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __evaluate_permissionx_expression(struct cil_permissionx *permx, struct cil_db *db) +{ + int rc; + + permx->perms = cil_malloc(sizeof(*permx->perms)); + ebitmap_init(permx->perms); + + rc = __cil_expr_to_bitmap(permx->expr_str, permx->perms, 0x10000, db); // max is one more than 0xFFFF + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to expand permissionx expression\n"); + ksu_ebitmap_destroy(permx->perms); + free(permx->perms); + permx->perms = NULL; + } + + return rc; +} + +static int __cil_permx_str_to_int(char *permx_str, uint16_t *val) +{ + char *endptr = NULL; + long lval = strtol(permx_str, &endptr, 0); + + if (*endptr != '\0') { + cil_log(CIL_ERR, "permissionx value %s not valid number\n", permx_str); + goto exit; + } + if (lval < 0x0000 || lval > 0xFFFF) { + cil_log(CIL_ERR, "permissionx value %s must be between 0x0000 and 0xFFFF\n", permx_str); + goto exit; + } + + *val = (uint16_t)lval; + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_permx_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db) +{ + int rc = SEPOL_ERR; + uint16_t val; + + rc = __cil_permx_str_to_int((char*)datum, &val); + if (rc != SEPOL_OK) { + goto exit; + } + + ebitmap_init(bitmap); + if (ksu_ebitmap_set_bit(bitmap, (unsigned int)val, 1)) { + cil_log(CIL_ERR, "Failed to set permissionx bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_perm_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db) +{ + struct cil_perm *perm = (struct cil_perm *)datum; + unsigned int value = perm->value; + + ebitmap_init(bitmap); + if (ksu_ebitmap_set_bit(bitmap, value, 1)) { + cil_log(CIL_INFO, "Failed to set perm bit\n"); + ksu_ebitmap_destroy(bitmap); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __evaluate_cat_expression(struct cil_cats *cats, struct cil_db *db) +{ + int rc = SEPOL_ERR; + ebitmap_t bitmap; + struct cil_list *new; + struct cil_list_item *curr; + + if (cats->evaluated == CIL_TRUE) { + return SEPOL_OK; + } + + if (cil_verify_is_list(cats->datum_expr, CIL_CAT)) { + return SEPOL_OK; + } + + ebitmap_init(&bitmap); + rc = __cil_expr_to_bitmap(cats->datum_expr, &bitmap, db->num_cats, db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to expand category expression to bitmap\n"); + ksu_ebitmap_destroy(&bitmap); + goto exit; + } + + cil_list_init(&new, CIL_CAT); + + cil_list_for_each(curr, db->catorder) { + struct cil_cat *cat = curr->data; + if (ksu_ebitmap_get_bit(&bitmap, cat->value)) { + cil_list_append(new, CIL_DATUM, cat); + } + } + + ksu_ebitmap_destroy(&bitmap); + cil_list_destroy(&cats->datum_expr, CIL_FALSE); + cats->datum_expr = new; + + cats->evaluated = CIL_TRUE; + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_cat_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *node = datum->nodes->head->data; + + ebitmap_init(bitmap); + + if (node->flavor == CIL_CATSET) { + struct cil_catset *catset = (struct cil_catset *)datum; + struct cil_list_item *curr; + if (catset->cats->evaluated == CIL_FALSE) { + rc = __evaluate_cat_expression(catset->cats, db); + if (rc != SEPOL_OK) goto exit; + } + for (curr = catset->cats->datum_expr->head; curr; curr = curr->next) { + struct cil_cat *cat = (struct cil_cat *)curr->data; + if (ksu_ebitmap_set_bit(bitmap, cat->value, 1)) { + cil_log(CIL_ERR, "Failed to set cat bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } + } else if (node->flavor == CIL_CATALIAS) { + struct cil_alias *alias = (struct cil_alias *)datum; + struct cil_cat *cat = alias->actual; + if (ksu_ebitmap_set_bit(bitmap, cat->value, 1)) { + cil_log(CIL_ERR, "Failed to set cat bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } else { + struct cil_cat *cat = (struct cil_cat *)datum; + if (ksu_ebitmap_set_bit(bitmap, cat->value, 1)) { + cil_log(CIL_ERR, "Failed to set cat bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap) +{ + int rc = SEPOL_ERR; + struct cil_symtab_datum *d1 = i1->data; + struct cil_symtab_datum *d2 = i2->data; + struct cil_tree_node *n1 = d1->nodes->head->data; + struct cil_tree_node *n2 = d2->nodes->head->data; + struct cil_cat *c1 = (struct cil_cat *)d1; + struct cil_cat *c2 = (struct cil_cat *)d2; + int i; + + if (n1->flavor == CIL_CATSET || n2->flavor == CIL_CATSET) { + cil_log(CIL_ERR, "Category sets cannont be used in a category range\n"); + goto exit; + } + + if (n1->flavor == CIL_CATALIAS) { + struct cil_alias *alias = (struct cil_alias *)d1; + c1 = alias->actual; + } + + if (n2->flavor == CIL_CATALIAS) { + struct cil_alias *alias = (struct cil_alias *)d2; + c2 = alias->actual; + } + + if (c1->value > c2->value) { + cil_log(CIL_ERR, "Invalid category range\n"); + goto exit; + } + + for (i = c1->value; i <= c2->value; i++) { + if (ksu_ebitmap_set_bit(bitmap, i, 1)) { + cil_log(CIL_ERR, "Failed to set cat bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap) +{ + int rc = SEPOL_ERR; + char *p1 = i1->data; + char *p2 = i2->data; + uint16_t v1; + uint16_t v2; + uint32_t i; + + rc = __cil_permx_str_to_int(p1, &v1); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_permx_str_to_int(p2, &v2); + if (rc != SEPOL_OK) { + goto exit; + } + + for (i = v1; i <= v2; i++) { + if (ksu_ebitmap_set_bit(bitmap, i, 1)) { + cil_log(CIL_ERR, "Failed to set permissionx bit\n"); + ksu_ebitmap_destroy(bitmap); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_expr_to_bitmap_helper(struct cil_list_item *curr, enum cil_flavor flavor, ebitmap_t *bitmap, int max, struct cil_db *db) +{ + int rc = SEPOL_ERR; + + if (curr->flavor == CIL_DATUM) { + switch (flavor) { + case CIL_TYPE: + rc = __cil_type_to_bitmap(curr->data, bitmap, db); + break; + case CIL_ROLE: + rc = __cil_role_to_bitmap(curr->data, bitmap, db); + break; + case CIL_USER: + rc = __cil_user_to_bitmap(curr->data, bitmap, db); + break; + case CIL_PERM: + rc = __cil_perm_to_bitmap(curr->data, bitmap, db); + break; + case CIL_CAT: + rc = __cil_cat_to_bitmap(curr->data, bitmap, db); + break; + default: + rc = SEPOL_ERR; + } + } else if (curr->flavor == CIL_LIST) { + struct cil_list *l = curr->data; + ebitmap_init(bitmap); + rc = __cil_expr_to_bitmap(l, bitmap, max, db); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(bitmap); + } + } else if (flavor == CIL_PERMISSIONX) { + // permissionx expressions aren't resolved into anything, so curr->flavor + // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those + rc = __cil_permx_to_bitmap(curr->data, bitmap, db); + } + + return rc; +} + +static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + enum cil_flavor flavor; + ebitmap_t tmp, b1, b2; + + if (expr == NULL || expr->head == NULL) { + return SEPOL_OK; + } + + curr = expr->head; + flavor = expr->flavor; + + if (curr->flavor == CIL_OP) { + enum cil_flavor op = (enum cil_flavor)(uintptr_t)curr->data; + + if (op == CIL_ALL) { + ebitmap_init(&b1); /* all zeros */ + rc = ebitmap_not(&tmp, &b1, max); + ksu_ebitmap_destroy(&b1); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to expand 'all' operator\n"); + ksu_ebitmap_destroy(&tmp); + goto exit; + } + } else if (op == CIL_RANGE) { + if (flavor == CIL_CAT) { + ebitmap_init(&tmp); + rc = __cil_cat_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to expand category range\n"); + ksu_ebitmap_destroy(&tmp); + goto exit; + } + } else if (flavor == CIL_PERMISSIONX) { + ebitmap_init(&tmp); + rc = __cil_permissionx_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to expand category range\n"); + ksu_ebitmap_destroy(&tmp); + goto exit; + } + } else { + cil_log(CIL_INFO, "Range operation only supported for categories permissionx\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = __cil_expr_to_bitmap_helper(curr->next, flavor, &b1, max, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to get first operand bitmap\n"); + goto exit; + } + + if (op == CIL_NOT) { + rc = ebitmap_not(&tmp, &b1, max); + ksu_ebitmap_destroy(&b1); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to NOT bitmap\n"); + ksu_ebitmap_destroy(&tmp); + goto exit; + } + } else { + rc = __cil_expr_to_bitmap_helper(curr->next->next, flavor, &b2, max, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to get second operand bitmap\n"); + ksu_ebitmap_destroy(&b1); + goto exit; + } + + if (op == CIL_OR) { + rc = ebitmap_or(&tmp, &b1, &b2); + } else if (op == CIL_AND) { + rc = ksu_ebitmap_and(&tmp, &b1, &b2); + } else if (op == CIL_XOR) { + rc = ebitmap_xor(&tmp, &b1, &b2); + } else { + rc = SEPOL_ERR; + } + ksu_ebitmap_destroy(&b1); + ksu_ebitmap_destroy(&b2); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to apply operator to bitmaps\n"); + ksu_ebitmap_destroy(&tmp); + goto exit; + } + } + } + } else { + ebitmap_init(&tmp); + for (;curr; curr = curr->next) { + rc = __cil_expr_to_bitmap_helper(curr, flavor, &b2, max, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to get operand in list\n"); + ksu_ebitmap_destroy(&tmp); + goto exit; + } + b1 = tmp; + rc = ebitmap_or(&tmp, &b1, &b2); + ksu_ebitmap_destroy(&b1); + ksu_ebitmap_destroy(&b2); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to OR operands in list\n"); + ksu_ebitmap_destroy(&tmp); + goto exit; + } + + } + } + + ebitmap_union(out, &tmp); + ksu_ebitmap_destroy(&tmp); + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_list_item *expr; + + ebitmap_init(out); + + if (expr_list == NULL) { + return SEPOL_OK; + } + + cil_list_for_each(expr, expr_list) { + ebitmap_t bitmap; + struct cil_list *l = (struct cil_list *)expr->data; + ebitmap_init(&bitmap); + rc = __cil_expr_to_bitmap(l, &bitmap, max, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to expand expression list to bitmap\n"); + ksu_ebitmap_destroy(&bitmap); + goto exit; + } + ebitmap_union(out, &bitmap); + ksu_ebitmap_destroy(&bitmap); + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int cil_typeattribute_used(struct cil_typeattribute *attr, struct cil_db *db) +{ + if (!attr->used) { + return CIL_FALSE; + } + + if (attr->used & CIL_ATTR_EXPAND_FALSE) { + return CIL_TRUE; + } + + if (attr->used & CIL_ATTR_EXPAND_TRUE) { + return CIL_FALSE; + } + + if (attr->used & CIL_ATTR_CONSTRAINT) { + return CIL_TRUE; + } + + if (db->attrs_expand_generated || attr->used == CIL_ATTR_NEVERALLOW) { + if (strcmp(DATUM(attr)->name, GEN_REQUIRE_ATTR) == 0) { + return CIL_FALSE; + } else if (strstr(DATUM(attr)->name, TYPEATTR_INFIX) != NULL) { + return CIL_FALSE; + } + + if (attr->used == CIL_ATTR_NEVERALLOW) { + return CIL_TRUE; + } + } + + if (attr->used == CIL_ATTR_AVRULE) { + if (ebitmap_cardinality(attr->types) < db->attrs_expand_size) { + return CIL_FALSE; + } + } + + return CIL_TRUE; +} + +static void __mark_neverallow_attrs(struct cil_list *expr_list) +{ + struct cil_list_item *curr; + + if (!expr_list) { + return; + } + + cil_list_for_each(curr, expr_list) { + if (curr->flavor == CIL_DATUM) { + if (FLAVOR(curr->data) == CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *attr = curr->data; + if (strstr(DATUM(attr)->name, TYPEATTR_INFIX)) { + __mark_neverallow_attrs(attr->expr_list); + } else { + attr->used |= CIL_ATTR_NEVERALLOW; + } + } + } else if (curr->flavor == CIL_LIST) { + __mark_neverallow_attrs(curr->data); + } + } +} + +static int __cil_post_db_neverallow_attr_helper(struct cil_tree_node *node, uint32_t *finished, __attribute__((unused)) void *extra_args) +{ + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: { + *finished = CIL_TREE_SKIP_HEAD; + break; + } + case CIL_TYPEATTRIBUTE: { + struct cil_typeattribute *attr = node->data; + if ((attr->used & CIL_ATTR_NEVERALLOW) && + strstr(DATUM(attr)->name, TYPEATTR_INFIX)) { + __mark_neverallow_attrs(attr->expr_list); + } + break; + } + default: + break; + } + + return SEPOL_OK; +} + +static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_db *db = extra_args; + + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: { + *finished = CIL_TREE_SKIP_HEAD; + break; + } + case CIL_TYPEATTRIBUTE: { + struct cil_typeattribute *attr = node->data; + if (attr->types == NULL) { + rc = __evaluate_type_expression(attr, db); + if (rc != SEPOL_OK) goto exit; + } + attr->keep = cil_typeattribute_used(attr, db); + break; + } + case CIL_ROLEATTRIBUTE: { + struct cil_roleattribute *attr = node->data; + if (attr->roles == NULL) { + rc = __evaluate_role_expression(attr, db); + if (rc != SEPOL_OK) goto exit; + } + break; + } + case CIL_AVRULEX: { + struct cil_avrule *rule = node->data; + if (rule->perms.x.permx_str == NULL) { + rc = __evaluate_permissionx_expression(rule->perms.x.permx, db); + if (rc != SEPOL_OK) goto exit; + } + break; + } + case CIL_PERMISSIONX: { + struct cil_permissionx *permx = node->data; + rc = __evaluate_permissionx_expression(permx, db); + if (rc != SEPOL_OK) goto exit; + break; + } + case CIL_USERATTRIBUTE: { + struct cil_userattribute *attr = node->data; + if (attr->users == NULL) { + rc = __evaluate_user_expression(attr, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + break; + } + default: + break; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_role_assign_types(struct cil_role *role, struct cil_symtab_datum *datum) +{ + struct cil_tree_node *node = datum->nodes->head->data; + + if (role->types == NULL) { + role->types = cil_malloc(sizeof(*role->types)); + ebitmap_init(role->types); + } + + if (node->flavor == CIL_TYPE) { + struct cil_type *type = (struct cil_type *)datum; + if (ksu_ebitmap_set_bit(role->types, type->value, 1)) { + cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n"); + goto exit; + } + } else if (node->flavor == CIL_TYPEALIAS) { + struct cil_alias *alias = (struct cil_alias *)datum; + struct cil_type *type = alias->actual; + if (ksu_ebitmap_set_bit(role->types, type->value, 1)) { + cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n"); + goto exit; + } + } else if (node->flavor == CIL_TYPEATTRIBUTE) { + struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; + ebitmap_union(role->types, attr->types); + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_post_db_roletype_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_db *db = extra_args; + + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: { + *finished = CIL_TREE_SKIP_HEAD; + break; + } + case CIL_ROLETYPE: { + struct cil_roletype *roletype = node->data; + struct cil_symtab_datum *role_datum = roletype->role; + struct cil_symtab_datum *type_datum = roletype->type; + struct cil_tree_node *role_node = role_datum->nodes->head->data; + + if (role_node->flavor == CIL_ROLEATTRIBUTE) { + struct cil_roleattribute *attr = roletype->role; + ebitmap_node_t *rnode; + unsigned int i; + + ebitmap_for_each_positive_bit(attr->roles, rnode, i) { + struct cil_role *role = NULL; + + role = db->val_to_role[i]; + + rc = __cil_role_assign_types(role, type_datum); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else { + struct cil_role *role = roletype->role; + + rc = __cil_role_assign_types(role, type_datum); + if (rc != SEPOL_OK) { + goto exit; + } + } + break; + } + default: + break; + } + + return SEPOL_OK; +exit: + cil_log(CIL_INFO, "cil_post_db_roletype_helper failed\n"); + return rc; +} + +static int __cil_user_assign_roles(struct cil_user *user, struct cil_symtab_datum *datum) +{ + struct cil_tree_node *node = datum->nodes->head->data; + struct cil_role *role = NULL; + struct cil_roleattribute *attr = NULL; + + if (user->roles == NULL) { + user->roles = cil_malloc(sizeof(*user->roles)); + ebitmap_init(user->roles); + } + + if (node->flavor == CIL_ROLE) { + role = (struct cil_role *)datum; + if (ksu_ebitmap_set_bit(user->roles, role->value, 1)) { + cil_log(CIL_INFO, "Failed to set bit in user roles bitmap\n"); + goto exit; + } + } else if (node->flavor == CIL_ROLEATTRIBUTE) { + attr = (struct cil_roleattribute *)datum; + ebitmap_union(user->roles, attr->roles); + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_post_db_userrole_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_db *db = extra_args; + struct cil_block *blk = NULL; + struct cil_userrole *userrole = NULL; + struct cil_symtab_datum *user_datum = NULL; + struct cil_symtab_datum *role_datum = NULL; + struct cil_tree_node *user_node = NULL; + struct cil_userattribute *u_attr = NULL; + unsigned int i; + struct cil_user *user = NULL; + ebitmap_node_t *unode = NULL; + + switch (node->flavor) { + case CIL_BLOCK: { + blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: { + *finished = CIL_TREE_SKIP_HEAD; + break; + } + case CIL_USERROLE: { + userrole = node->data; + user_datum = userrole->user; + role_datum = userrole->role; + user_node = user_datum->nodes->head->data; + + if (user_node->flavor == CIL_USERATTRIBUTE) { + u_attr = userrole->user; + + ebitmap_for_each_positive_bit(u_attr->users, unode, i) { + user = db->val_to_user[i]; + + rc = __cil_user_assign_roles(user, role_datum); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else { + user = userrole->user; + + rc = __cil_user_assign_roles(user, role_datum); + if (rc != SEPOL_OK) { + goto exit; + } + } + + break; + } + default: + break; + } + + return SEPOL_OK; +exit: + cil_log(CIL_INFO, "cil_post_db_userrole_helper failed\n"); + return rc; +} + +static int __evaluate_level_expression(struct cil_level *level, struct cil_db *db) +{ + if (level->cats != NULL) { + return __evaluate_cat_expression(level->cats, db); + } + + return SEPOL_OK; +} + +static int __evaluate_levelrange_expression(struct cil_levelrange *levelrange, struct cil_db *db) +{ + int rc = SEPOL_OK; + + if (levelrange->low != NULL && levelrange->low->cats != NULL) { + rc = __evaluate_cat_expression(levelrange->low->cats, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + if (levelrange->high != NULL && levelrange->high->cats != NULL) { + rc = __evaluate_cat_expression(levelrange->high->cats, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + +exit: + return rc; +} + +static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_db *db = extra_args; + + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: { + *finished = CIL_TREE_SKIP_HEAD; + break; + } + case CIL_CATSET: { + struct cil_catset *catset = node->data; + rc = __evaluate_cat_expression(catset->cats, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_SENSCAT: { + struct cil_senscat *senscat = node->data; + rc = __evaluate_cat_expression(senscat->cats, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_LEVEL: { + rc = __evaluate_level_expression(node->data, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_LEVELRANGE: { + rc = __evaluate_levelrange_expression(node->data, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_USER: { + struct cil_user *user = node->data; + rc = __evaluate_level_expression(user->dftlevel, db); + if (rc != SEPOL_OK) { + goto exit; + } + rc = __evaluate_levelrange_expression(user->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_SELINUXUSERDEFAULT: + case CIL_SELINUXUSER: { + struct cil_selinuxuser *selinuxuser = node->data; + rc = __evaluate_levelrange_expression(selinuxuser->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_RANGETRANSITION: { + struct cil_rangetransition *rangetrans = node->data; + rc = __evaluate_levelrange_expression(rangetrans->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_CONTEXT: { + struct cil_context *context = node->data; + rc = __evaluate_levelrange_expression(context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_SIDCONTEXT: { + struct cil_sidcontext *sidcontext = node->data; + rc = __evaluate_levelrange_expression(sidcontext->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_FILECON: { + struct cil_filecon *filecon = node->data; + if (filecon->context) { + rc = __evaluate_levelrange_expression(filecon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + break; + } + case CIL_IBPKEYCON: { + struct cil_ibpkeycon *ibpkeycon = node->data; + + rc = __evaluate_levelrange_expression(ibpkeycon->context->range, db); + if (rc != SEPOL_OK) + goto exit; + break; + } + case CIL_IBENDPORTCON: { + struct cil_ibendportcon *ibendportcon = node->data; + + rc = __evaluate_levelrange_expression(ibendportcon->context->range, db); + if (rc != SEPOL_OK) + goto exit; + break; + } + case CIL_PORTCON: { + struct cil_portcon *portcon = node->data; + rc = __evaluate_levelrange_expression(portcon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_NODECON: { + struct cil_nodecon *nodecon = node->data; + rc = __evaluate_levelrange_expression(nodecon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_GENFSCON: { + struct cil_genfscon *genfscon = node->data; + rc = __evaluate_levelrange_expression(genfscon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_NETIFCON: { + struct cil_netifcon *netifcon = node->data; + rc = __evaluate_levelrange_expression(netifcon->if_context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + rc = __evaluate_levelrange_expression(netifcon->packet_context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_PIRQCON: { + struct cil_pirqcon *pirqcon = node->data; + rc = __evaluate_levelrange_expression(pirqcon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_IOMEMCON: { + struct cil_iomemcon *iomemcon = node->data; + rc = __evaluate_levelrange_expression(iomemcon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_IOPORTCON: { + struct cil_ioportcon *ioportcon = node->data; + rc = __evaluate_levelrange_expression(ioportcon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_PCIDEVICECON: { + struct cil_pcidevicecon *pcidevicecon = node->data; + rc = __evaluate_levelrange_expression(pcidevicecon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_DEVICETREECON: { + struct cil_devicetreecon *devicetreecon = node->data; + rc = __evaluate_levelrange_expression(devicetreecon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_FSUSE: { + struct cil_fsuse *fsuse = node->data; + rc = __evaluate_levelrange_expression(fsuse->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + default: + break; + } + + return SEPOL_OK; + +exit: + return rc; +} + +struct perm_to_list { + enum cil_flavor flavor; + ebitmap_t *perms; + struct cil_list *new_list; +}; + +static int __perm_bits_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct perm_to_list *perm_args = (struct perm_to_list *)args; + ebitmap_t *perms = perm_args->perms; + struct cil_list *new_list = perm_args->new_list; + struct cil_perm *perm = (struct cil_perm *)d; + unsigned int value = perm->value; + + if (!ksu_ebitmap_get_bit(perms, value)) { + return SEPOL_OK; + } + + cil_list_append(new_list, CIL_DATUM, d); + + return SEPOL_OK; +} + +static int __evaluate_perm_expression(struct cil_list *perms, enum cil_flavor flavor, symtab_t *class_symtab, symtab_t *common_symtab, unsigned int num_perms, struct cil_list **new_list, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct perm_to_list args; + ebitmap_t bitmap; + + if (cil_verify_is_list(perms, CIL_PERM)) { + return SEPOL_OK; + } + + ebitmap_init(&bitmap); + rc = __cil_expr_to_bitmap(perms, &bitmap, num_perms, db); + if (rc != SEPOL_OK) { + ksu_ebitmap_destroy(&bitmap); + goto exit; + } + + cil_list_init(new_list, flavor); + + args.flavor = flavor; + args.perms = &bitmap; + args.new_list = *new_list; + + cil_symtab_map(class_symtab, __perm_bits_to_list, &args); + + if (common_symtab != NULL) { + cil_symtab_map(common_symtab, __perm_bits_to_list, &args); + } + + ksu_ebitmap_destroy(&bitmap); + return SEPOL_OK; + +exit: + return rc; +} + +static int __evaluate_classperms(struct cil_classperms *cp, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_class *class = cp->class; + struct cil_class *common = class->common; + symtab_t *common_symtab = NULL; + struct cil_list *new_list = NULL; + + if (common) { + common_symtab = &common->perms; + } + + rc = __evaluate_perm_expression(cp->perms, CIL_PERM, &class->perms, common_symtab, class->num_perms, &new_list, db); + if (rc != SEPOL_OK) { + goto exit; + } + + if (new_list == NULL) { + return SEPOL_OK; + } + + cil_list_destroy(&cp->perms, CIL_FALSE); + + cp->perms = new_list; + + return SEPOL_OK; + +exit: + return rc; +} + +static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + + cil_list_for_each(curr, classperms) { + if (curr->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = curr->data; + if (FLAVOR(cp->class) == CIL_CLASS) { + rc = __evaluate_classperms(cp, db); + if (rc != SEPOL_OK) { + goto exit; + } + } else { /* MAP */ + struct cil_list_item *i = NULL; + rc = __evaluate_classperms(cp, db); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_for_each(i, cp->perms) { + struct cil_perm *cmp = i->data; + rc = __evaluate_classperms_list(cmp->classperms, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + rc = __evaluate_classperms_list(cp->classperms, db); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +struct class_map_args { + struct cil_db *db; + int rc; +}; + +static int __evaluate_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct class_map_args *map_args = args; + struct cil_perm *cmp = (struct cil_perm *)d; + + int rc = __evaluate_classperms_list(cmp->classperms, map_args->db); + + if (rc != SEPOL_OK) { + map_args->rc = rc; + } + + return SEPOL_OK; +} + +static int __evaluate_map_class(struct cil_class *mc, struct cil_db *db) +{ + struct class_map_args map_args; + + map_args.db = db; + map_args.rc = SEPOL_OK; + cil_symtab_map(&mc->perms, __evaluate_map_perm_classperms, &map_args); + + return map_args.rc; +} + +static int __cil_post_db_classperms_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_db *db = extra_args; + + switch (node->flavor) { + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_MACRO: + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_MAP_CLASS: { + rc = __evaluate_map_class(node->data, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_CLASSPERMISSION: { + struct cil_classpermission *cp = node->data; + rc = __evaluate_classperms_list(cp->classperms, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_AVRULE: { + struct cil_avrule *avrule = node->data; + rc = __evaluate_classperms_list(avrule->perms.classperms, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + case CIL_CONSTRAIN: + case CIL_MLSCONSTRAIN: { + struct cil_constrain *constrain = node->data; + rc = __evaluate_classperms_list(constrain->classperms, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } + default: + break; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_post_report_conflict(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + struct cil_list_item *li = extra_args; + + if (node->flavor == CIL_BLOCK) { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + } else if (node->flavor == CIL_MACRO) { + *finished = CIL_TREE_SKIP_HEAD; + } else if (node->flavor == li->flavor) { + if (node->data == li->data) { + char *path = cil_tree_get_cil_path(node); + cil_log(CIL_WARN, " at %s:%d\n", path, node->line); + } + } + return SEPOL_OK; +} + +static int __cil_post_process_context_rules(struct cil_sort *sort, int (*compar)(const void *, const void *), int (*concompar)(const void *, const void *), struct cil_db *db, enum cil_flavor flavor, const char *flavor_str) +{ + uint32_t count = sort->count; + uint32_t i = 0, j, removed = 0; + int conflicting = 0; + int rc = SEPOL_OK; + enum cil_log_level log_level = cil_get_log_level(); + + if (count < 2) { + return SEPOL_OK; + } + + qsort(sort->array, sort->count, sizeof(sort->array), compar); + + for (j=1; jarray[i], &sort->array[j]) != 0) { + i++; + if (conflicting >= 4) { + /* 2 rules were written when conflicting == 1 */ + cil_log(CIL_WARN, " Only first 4 of %d conflicting rules shown\n", conflicting); + } + conflicting = 0; + } else { + removed++; + if (!db->multiple_decls || concompar(&sort->array[i], &sort->array[j]) != 0) { + conflicting++; + if (log_level >= CIL_WARN) { + struct cil_list_item li; + int rc2; + li.flavor = flavor; + if (conflicting == 1) { + cil_log(CIL_WARN, "Found conflicting %s rules\n", flavor_str); + rc = SEPOL_ERR; + li.data = sort->array[i]; + rc2 = cil_tree_walk(db->ast->root, __cil_post_report_conflict, + NULL, NULL, &li); + if (rc2 != SEPOL_OK) goto exit; + } + if (conflicting < 4 || log_level > CIL_WARN) { + li.data = sort->array[j]; + rc2 = cil_tree_walk(db->ast->root, __cil_post_report_conflict, + NULL, NULL, &li); + if (rc2 != SEPOL_OK) goto exit; + } + } + } + } + if (i != j && !conflicting) { + sort->array[i] = sort->array[j]; + } + } + sort->count = count - removed; + +exit: + return rc; +} + +static int cil_post_db(struct cil_db *db) +{ + int rc = SEPOL_ERR; + + rc = cil_tree_walk(db->ast->root, __cil_post_db_count_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure during cil database count helper\n"); + goto exit; + } + + rc = cil_tree_walk(db->ast->root, __cil_post_db_array_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure during cil database array helper\n"); + goto exit; + } + + rc = cil_tree_walk(db->ast->root, __cil_post_db_neverallow_attr_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to mark attributes used by generated attributes used in neverallow rules\n"); + goto exit; + } + + rc = cil_tree_walk(db->ast->root, __cil_post_db_attr_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to create attribute bitmaps\n"); + goto exit; + } + + rc = cil_tree_walk(db->ast->root, __cil_post_db_roletype_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed during roletype association\n"); + goto exit; + } + + rc = cil_tree_walk(db->ast->root, __cil_post_db_userrole_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed during userrole association\n"); + goto exit; + } + + rc = cil_tree_walk(db->ast->root, __cil_post_db_classperms_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to evaluate class mapping permissions expressions\n"); + goto exit; + } + + rc = cil_tree_walk(db->ast->root, __cil_post_db_cat_helper, NULL, NULL, db); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failed to evaluate category expressions\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->netifcon, cil_post_netifcon_compare, cil_post_netifcon_context_compare, db, CIL_NETIFCON, CIL_KEY_NETIFCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing netifcon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->genfscon, cil_post_genfscon_compare, cil_post_genfscon_context_compare, db, CIL_GENFSCON, CIL_KEY_GENFSCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing genfscon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->ibpkeycon, cil_post_ibpkeycon_compare, cil_post_ibpkeycon_context_compare, db, CIL_IBPKEYCON, CIL_KEY_IBPKEYCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing ibpkeycon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->ibendportcon, cil_post_ibendportcon_compare, cil_post_ibendportcon_context_compare, db, CIL_IBENDPORTCON, CIL_KEY_IBENDPORTCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing ibendportcon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->portcon, cil_post_portcon_compare, cil_post_portcon_context_compare, db, CIL_PORTCON, CIL_KEY_PORTCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing portcon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->nodecon, cil_post_nodecon_compare, cil_post_nodecon_context_compare, db, CIL_NODECON, CIL_KEY_NODECON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing nodecon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->fsuse, cil_post_fsuse_compare, cil_post_fsuse_context_compare, db, CIL_FSUSE, CIL_KEY_FSUSE); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing fsuse rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->filecon, cil_post_filecon_compare, cil_post_filecon_context_compare, db, CIL_FILECON, CIL_KEY_FILECON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing filecon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->pirqcon, cil_post_pirqcon_compare, cil_post_pirqcon_context_compare, db, CIL_PIRQCON, CIL_KEY_IOMEMCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing pirqcon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->iomemcon, cil_post_iomemcon_compare, cil_post_iomemcon_context_compare, db, CIL_IOMEMCON, CIL_KEY_IOMEMCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing iomemcon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->ioportcon, cil_post_ioportcon_compare, cil_post_ioportcon_context_compare, db, CIL_IOPORTCON, CIL_KEY_IOPORTCON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing ioportcon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->pcidevicecon, cil_post_pcidevicecon_compare, cil_post_pcidevicecon_context_compare, db, CIL_PCIDEVICECON, CIL_KEY_PCIDEVICECON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing pcidevicecon rules\n"); + goto exit; + } + + rc = __cil_post_process_context_rules(db->devicetreecon, cil_post_devicetreecon_compare, cil_post_devicetreecon_context_compare, db, CIL_DEVICETREECON, CIL_KEY_DEVICETREECON); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Problems processing devicetreecon rules\n"); + goto exit; + } + +exit: + return rc; +} + +static int cil_post_verify(struct cil_db *db) +{ + int rc = SEPOL_ERR; + int avrule_cnt = 0; + int handleunknown = -1; + int mls = -1; + int nseuserdflt = 0; + int pass = 0; + struct cil_args_verify extra_args; + struct cil_complex_symtab csymtab; + + cil_complex_symtab_init(&csymtab, CIL_CLASS_SYM_SIZE); + + extra_args.db = db; + extra_args.csymtab = &csymtab; + extra_args.avrule_cnt = &avrule_cnt; + extra_args.handleunknown = &handleunknown; + extra_args.mls = &mls; + extra_args.nseuserdflt = &nseuserdflt; + extra_args.pass = &pass; + + for (pass = 0; pass < 2; pass++) { + rc = cil_tree_walk(db->ast->root, __cil_verify_helper, NULL, NULL, &extra_args); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to verify cil database\n"); + goto exit; + } + } + + if (db->handle_unknown == -1) { + if (handleunknown == -1) { + db->handle_unknown = SEPOL_DENY_UNKNOWN; + } else { + db->handle_unknown = handleunknown; + } + } + + if (db->mls == -1) { + if (mls == -1) { + db->mls = CIL_FALSE; + } else { + db->mls = mls; + } + } + + if (avrule_cnt == 0) { + cil_log(CIL_ERR, "Policy must include at least one avrule\n"); + rc = SEPOL_ERR; + goto exit; + } + + if (nseuserdflt > 1) { + cil_log(CIL_ERR, "Policy cannot contain more than one selinuxuserdefault, found: %d\n", nseuserdflt); + rc = SEPOL_ERR; + goto exit; + } + +exit: + cil_complex_symtab_destroy(&csymtab); + return rc; +} + +static int cil_pre_verify(struct cil_db *db) +{ + int rc = SEPOL_ERR; + struct cil_args_verify extra_args; + + extra_args.db = db; + + rc = cil_tree_walk(db->ast->root, __cil_pre_verify_helper, NULL, NULL, &extra_args); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to verify cil database\n"); + goto exit; + } + +exit: + return rc; +} + +int cil_post_process(struct cil_db *db) +{ + int rc = SEPOL_ERR; + + rc = cil_pre_verify(db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to verify cil database\n"); + goto exit; + } + + rc = cil_post_db(db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed post db handling\n"); + goto exit; + } + + rc = cil_post_verify(db); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to verify cil database\n"); + goto exit; + } + +exit: + return rc; + +} diff --git a/kernel/libsepol/cil/src/cil_post.h b/kernel/libsepol/cil/src/cil_post.h new file mode 100644 index 00000000..b1d2206f --- /dev/null +++ b/kernel/libsepol/cil/src/cil_post.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_POST_H_ +#define CIL_POST_H_ + +int cil_post_filecon_compare(const void *a, const void *b); +int cil_post_ibpkeycon_compare(const void *a, const void *b); +int cil_post_portcon_compare(const void *a, const void *b); +int cil_post_ibendportcon_compare(const void *a, const void *b); +int cil_post_genfscon_compare(const void *a, const void *b); +int cil_post_netifcon_compare(const void *a, const void *b); +int cil_post_nodecon_compare(const void *a, const void *b); +int cil_post_fsuse_compare(const void *a, const void *b); + +int cil_post_context_sort(struct cil_db *db); + +int cil_post_process(struct cil_db *db); + +#endif diff --git a/kernel/libsepol/cil/src/cil_reset_ast.c b/kernel/libsepol/cil/src/cil_reset_ast.c new file mode 100644 index 00000000..0864d7ef --- /dev/null +++ b/kernel/libsepol/cil/src/cil_reset_ast.c @@ -0,0 +1,660 @@ + +#include "cil_internal.h" +#include "cil_log.h" +#include "cil_list.h" +#include "cil_reset_ast.h" +#include "cil_symtab.h" + +static inline void cil_reset_classperms_list(struct cil_list *cp_list); +static inline void cil_reset_level(struct cil_level *level); +static inline void cil_reset_levelrange(struct cil_levelrange *levelrange); +static inline void cil_reset_context(struct cil_context *context); + + +static int __class_reset_perm_values(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct cil_perm *perm = (struct cil_perm *)d; + + perm->value -= *((int *)args); + + return SEPOL_OK; +} + +static void cil_reset_class(struct cil_class *class) +{ + if (class->common != NULL) { + /* Must assume that the common has been destroyed */ + int num_common_perms = class->num_perms - class->perms.nprim; + cil_symtab_map(&class->perms, __class_reset_perm_values, &num_common_perms); + /* during a re-resolve, we need to reset the common, so a classcommon + * statement isn't seen as a duplicate */ + class->num_perms = class->perms.nprim; + class->common = NULL; /* Must make this NULL or there will be an error when re-resolving */ + } + class->ordered = CIL_FALSE; +} + +static void cil_reset_perm(struct cil_perm *perm) +{ + cil_list_destroy(&perm->classperms, CIL_FALSE); +} + +static inline void cil_reset_classperms(struct cil_classperms *cp) +{ + if (cp == NULL) { + return; + } + + cp->class = NULL; + cil_list_destroy(&cp->perms, CIL_FALSE); +} + +static void cil_reset_classpermission(struct cil_classpermission *cp) +{ + if (cp == NULL) { + return; + } + + cil_list_destroy(&cp->classperms, CIL_FALSE); +} + +static void cil_reset_classperms_set(struct cil_classperms_set *cp_set) +{ + if (cp_set == NULL || cp_set->set == NULL) { + return; + } + + if (cp_set->set->datum.name == NULL) { + cil_reset_classperms_list(cp_set->set->classperms); + } + + cp_set->set = NULL; +} + +static inline void cil_reset_classperms_list(struct cil_list *cp_list) +{ + struct cil_list_item *curr; + + if (cp_list == NULL) { + return; + } + + cil_list_for_each(curr, cp_list) { + if (curr->flavor == CIL_CLASSPERMS) { /* KERNEL or MAP */ + cil_reset_classperms(curr->data); + } else if (curr->flavor == CIL_CLASSPERMS_SET) { /* SET */ + cil_reset_classperms_set(curr->data); + } + } +} + +static void cil_reset_classpermissionset(struct cil_classpermissionset *cps) +{ + cil_reset_classperms_list(cps->classperms); +} + +static void cil_reset_classmapping(struct cil_classmapping *cm) +{ + cil_reset_classperms_list(cm->classperms); +} + +static void cil_reset_alias(struct cil_alias *alias) +{ + /* reset actual to NULL during a re-resolve */ + alias->actual = NULL; +} + +static void cil_reset_user(struct cil_user *user) +{ + /* reset the bounds to NULL during a re-resolve */ + user->bounds = NULL; + user->dftlevel = NULL; + user->range = NULL; +} + +static void cil_reset_userattr(struct cil_userattribute *attr) +{ + struct cil_list_item *expr = NULL; + struct cil_list_item *next = NULL; + + /* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a userattribute statement */ + if (attr->expr_list != NULL) { + /* we don't want to destroy the expression stacks (cil_list) inside + * this list cil_list_destroy destroys sublists, so we need to do it + * manually */ + expr = attr->expr_list->head; + while (expr != NULL) { + next = expr->next; + cil_list_item_destroy(&expr, CIL_FALSE); + expr = next; + } + free(attr->expr_list); + attr->expr_list = NULL; + } +} + +static void cil_reset_userattributeset(struct cil_userattributeset *uas) +{ + cil_list_destroy(&uas->datum_expr, CIL_FALSE); +} + +static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser) +{ + selinuxuser->user = NULL; + if (selinuxuser->range_str == NULL) { + cil_reset_levelrange(selinuxuser->range); + } else { + selinuxuser->range = NULL; + } +} + +static void cil_reset_role(struct cil_role *role) +{ + /* reset the bounds to NULL during a re-resolve */ + role->bounds = NULL; +} + +static void cil_reset_roleattr(struct cil_roleattribute *attr) +{ + /* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a attributeroles statement */ + if (attr->expr_list != NULL) { + /* we don't want to destroy the expression stacks (cil_list) inside + * this list cil_list_destroy destroys sublists, so we need to do it + * manually */ + struct cil_list_item *expr = attr->expr_list->head; + while (expr != NULL) { + struct cil_list_item *next = expr->next; + cil_list_item_destroy(&expr, CIL_FALSE); + expr = next; + } + free(attr->expr_list); + attr->expr_list = NULL; + } +} + +static void cil_reset_roleattributeset(struct cil_roleattributeset *ras) +{ + cil_list_destroy(&ras->datum_expr, CIL_FALSE); +} + +static void cil_reset_type(struct cil_type *type) +{ + /* reset the bounds to NULL during a re-resolve */ + type->bounds = NULL; +} + +static void cil_reset_typeattr(struct cil_typeattribute *attr) +{ + /* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a attributetypes statement */ + if (attr->expr_list != NULL) { + /* we don't want to destroy the expression stacks (cil_list) inside + * this list cil_list_destroy destroys sublists, so we need to do it + * manually */ + struct cil_list_item *expr = attr->expr_list->head; + while (expr != NULL) { + struct cil_list_item *next = expr->next; + cil_list_item_destroy(&expr, CIL_FALSE); + expr = next; + } + free(attr->expr_list); + attr->expr_list = NULL; + } + attr->used = CIL_FALSE; + attr->keep = CIL_FALSE; +} + +static void cil_reset_typeattributeset(struct cil_typeattributeset *tas) +{ + cil_list_destroy(&tas->datum_expr, CIL_FALSE); +} + +static void cil_reset_expandtypeattribute(struct cil_expandtypeattribute *expandattr) +{ + cil_list_destroy(&expandattr->attr_datums, CIL_FALSE); +} + +static void cil_reset_avrule(struct cil_avrule *rule) +{ + cil_reset_classperms_list(rule->perms.classperms); +} + +static void cil_reset_rangetransition(struct cil_rangetransition *rangetrans) +{ + if (rangetrans->range_str == NULL) { + cil_reset_levelrange(rangetrans->range); + } else { + rangetrans->range = NULL; + } +} + +static void cil_reset_sens(struct cil_sens *sens) +{ + /* during a re-resolve, we need to reset the categories associated with + * this sensitivity from a (sensitivitycategory) statement */ + cil_list_destroy(&sens->cats_list, CIL_FALSE); + sens->ordered = CIL_FALSE; +} + +static void cil_reset_cat(struct cil_cat *cat) +{ + cat->ordered = CIL_FALSE; +} + +static inline void cil_reset_cats(struct cil_cats *cats) +{ + if (cats != NULL) { + cats->evaluated = CIL_FALSE; + cil_list_destroy(&cats->datum_expr, CIL_FALSE); + } +} + + +static void cil_reset_senscat(struct cil_senscat *senscat) +{ + cil_reset_cats(senscat->cats); +} + +static void cil_reset_catset(struct cil_catset *catset) +{ + cil_reset_cats(catset->cats); +} + +static inline void cil_reset_level(struct cil_level *level) +{ + level->sens = NULL; + cil_reset_cats(level->cats); +} + +static inline void cil_reset_levelrange(struct cil_levelrange *levelrange) +{ + if (levelrange->low_str == NULL) { + cil_reset_level(levelrange->low); + } else { + levelrange->low = NULL; + } + + if (levelrange->high_str == NULL) { + cil_reset_level(levelrange->high); + } else { + levelrange->high = NULL; + } +} + +static inline void cil_reset_userlevel(struct cil_userlevel *userlevel) +{ + if (userlevel->level_str == NULL) { + cil_reset_level(userlevel->level); + } else { + userlevel->level = NULL; + } +} + +static inline void cil_reset_userrange(struct cil_userrange *userrange) +{ + if (userrange->range_str == NULL) { + cil_reset_levelrange(userrange->range); + } else { + userrange->range = NULL; + } +} + +static inline void cil_reset_context(struct cil_context *context) +{ + if (!context) { + return; + } + if (context->range_str == NULL) { + cil_reset_levelrange(context->range); + } else { + context->range = NULL; + } +} + +static void cil_reset_sidcontext(struct cil_sidcontext *sidcontext) +{ + if (sidcontext->context_str == NULL) { + cil_reset_context(sidcontext->context); + } else { + sidcontext->context = NULL; + } +} + +static void cil_reset_filecon(struct cil_filecon *filecon) +{ + if (filecon->context_str == NULL) { + cil_reset_context(filecon->context); + } else { + filecon->context = NULL; + } +} + +static void cil_reset_ibpkeycon(struct cil_ibpkeycon *ibpkeycon) +{ + if (ibpkeycon->context_str == NULL) { + cil_reset_context(ibpkeycon->context); + } else { + ibpkeycon->context = NULL; + } +} + +static void cil_reset_portcon(struct cil_portcon *portcon) +{ + if (portcon->context_str == NULL) { + cil_reset_context(portcon->context); + } else { + portcon->context = NULL; + } +} + +static void cil_reset_nodecon(struct cil_nodecon *nodecon) +{ + if (nodecon->context_str == NULL) { + cil_reset_context(nodecon->context); + } else { + nodecon->context = NULL; + } +} + +static void cil_reset_genfscon(struct cil_genfscon *genfscon) +{ + if (genfscon->context_str == NULL) { + cil_reset_context(genfscon->context); + } else { + genfscon->context = NULL; + } +} + +static void cil_reset_netifcon(struct cil_netifcon *netifcon) +{ + if (netifcon->if_context_str == NULL) { + cil_reset_context(netifcon->if_context); + } else { + netifcon->if_context = NULL; + } + + if (netifcon->packet_context_str == NULL) { + cil_reset_context(netifcon->packet_context); + } else { + netifcon->packet_context = NULL; + } +} + +static void cil_reset_ibendportcon(struct cil_ibendportcon *ibendportcon) +{ + if (ibendportcon->context_str == NULL) { + cil_reset_context(ibendportcon->context); + } else { + ibendportcon->context = NULL; + } +} + +static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon) +{ + if (pirqcon->context_str == NULL) { + cil_reset_context(pirqcon->context); + } else { + pirqcon->context = NULL; + } +} + +static void cil_reset_iomemcon(struct cil_iomemcon *iomemcon) +{ + if (iomemcon->context_str == NULL) { + cil_reset_context(iomemcon->context); + } else { + iomemcon->context = NULL; + } +} + +static void cil_reset_ioportcon(struct cil_ioportcon *ioportcon) +{ + if (ioportcon->context_str == NULL) { + cil_reset_context(ioportcon->context); + } else { + ioportcon->context = NULL; + } +} + +static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon) +{ + if (pcidevicecon->context_str == NULL) { + cil_reset_context(pcidevicecon->context); + } else { + pcidevicecon->context = NULL; + } +} + +static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon) +{ + if (devicetreecon->context_str == NULL) { + cil_reset_context(devicetreecon->context); + } else { + devicetreecon->context = NULL; + } +} + +static void cil_reset_fsuse(struct cil_fsuse *fsuse) +{ + if (fsuse->context_str == NULL) { + cil_reset_context(fsuse->context); + } else { + fsuse->context = NULL; + } +} + +static void cil_reset_sid(struct cil_sid *sid) +{ + /* reset the context to NULL during a re-resolve */ + sid->context = NULL; + sid->ordered = CIL_FALSE; +} + +static void cil_reset_constrain(struct cil_constrain *con) +{ + cil_reset_classperms_list(con->classperms); + cil_list_destroy(&con->datum_expr, CIL_FALSE); +} + +static void cil_reset_validatetrans(struct cil_validatetrans *vt) +{ + cil_list_destroy(&vt->datum_expr, CIL_FALSE); +} + +static void cil_reset_default(struct cil_default *def) +{ + cil_list_destroy(&def->class_datums, CIL_FALSE); +} + +static void cil_reset_defaultrange(struct cil_defaultrange *def) +{ + cil_list_destroy(&def->class_datums, CIL_FALSE); +} + +static void cil_reset_booleanif(struct cil_booleanif *bif) +{ + cil_list_destroy(&bif->datum_expr, CIL_FALSE); +} + +static int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, __attribute__((unused)) void *extra_args) +{ + switch (node->flavor) { + case CIL_CLASS: + cil_reset_class(node->data); + break; + case CIL_PERM: + case CIL_MAP_PERM: + cil_reset_perm(node->data); + break; + case CIL_CLASSPERMISSION: + cil_reset_classpermission(node->data); + break; + case CIL_CLASSPERMISSIONSET: + cil_reset_classpermissionset(node->data); + break; + case CIL_CLASSMAPPING: + cil_reset_classmapping(node->data); + break; + case CIL_TYPEALIAS: + case CIL_SENSALIAS: + case CIL_CATALIAS: + cil_reset_alias(node->data); + break; + case CIL_USERRANGE: + cil_reset_userrange(node->data); + break; + case CIL_USERLEVEL: + cil_reset_userlevel(node->data); + break; + case CIL_USER: + cil_reset_user(node->data); + break; + case CIL_USERATTRIBUTE: + cil_reset_userattr(node->data); + break; + case CIL_USERATTRIBUTESET: + cil_reset_userattributeset(node->data); + break; + case CIL_SELINUXUSERDEFAULT: + case CIL_SELINUXUSER: + cil_reset_selinuxuser(node->data); + break; + case CIL_ROLE: + cil_reset_role(node->data); + break; + case CIL_ROLEATTRIBUTE: + cil_reset_roleattr(node->data); + break; + case CIL_ROLEATTRIBUTESET: + cil_reset_roleattributeset(node->data); + break; + case CIL_TYPE: + cil_reset_type(node->data); + break; + case CIL_TYPEATTRIBUTE: + cil_reset_typeattr(node->data); + break; + case CIL_TYPEATTRIBUTESET: + cil_reset_typeattributeset(node->data); + break; + case CIL_EXPANDTYPEATTRIBUTE: + cil_reset_expandtypeattribute(node->data); + break; + case CIL_RANGETRANSITION: + cil_reset_rangetransition(node->data); + break; + case CIL_AVRULE: + cil_reset_avrule(node->data); + break; + case CIL_SENS: + cil_reset_sens(node->data); + break; + case CIL_CAT: + cil_reset_cat(node->data); + break; + case CIL_SENSCAT: + cil_reset_senscat(node->data); + break; + case CIL_CATSET: + cil_reset_catset(node->data); + break; + case CIL_LEVEL: + cil_reset_level(node->data); + break; + case CIL_LEVELRANGE: + cil_reset_levelrange(node->data); + break; + case CIL_CONTEXT: + cil_reset_context(node->data); + break; + case CIL_SIDCONTEXT: + cil_reset_sidcontext(node->data); + break; + case CIL_FILECON: + cil_reset_filecon(node->data); + break; + case CIL_IBPKEYCON: + cil_reset_ibpkeycon(node->data); + break; + case CIL_IBENDPORTCON: + cil_reset_ibendportcon(node->data); + break; + case CIL_PORTCON: + cil_reset_portcon(node->data); + break; + case CIL_NODECON: + cil_reset_nodecon(node->data); + break; + case CIL_GENFSCON: + cil_reset_genfscon(node->data); + break; + case CIL_NETIFCON: + cil_reset_netifcon(node->data); + break; + case CIL_PIRQCON: + cil_reset_pirqcon(node->data); + break; + case CIL_IOMEMCON: + cil_reset_iomemcon(node->data); + break; + case CIL_IOPORTCON: + cil_reset_ioportcon(node->data); + break; + case CIL_PCIDEVICECON: + cil_reset_pcidevicecon(node->data); + break; + case CIL_DEVICETREECON: + cil_reset_devicetreecon(node->data); + break; + case CIL_FSUSE: + cil_reset_fsuse(node->data); + break; + case CIL_SID: + cil_reset_sid(node->data); + break; + case CIL_CONSTRAIN: + case CIL_MLSCONSTRAIN: + cil_reset_constrain(node->data); + break; + case CIL_VALIDATETRANS: + case CIL_MLSVALIDATETRANS: + cil_reset_validatetrans(node->data); + break; + case CIL_DEFAULTUSER: + case CIL_DEFAULTROLE: + case CIL_DEFAULTTYPE: + cil_reset_default(node->data); + break; + case CIL_DEFAULTRANGE: + cil_reset_defaultrange(node->data); + break; + case CIL_BOOLEANIF: + cil_reset_booleanif(node->data); + break; + case CIL_TUNABLEIF: + case CIL_CALL: + break; /* Not effected by optional block disabling */ + case CIL_MACRO: + case CIL_SIDORDER: + case CIL_CLASSORDER: + case CIL_CATORDER: + case CIL_SENSITIVITYORDER: + break; /* Nothing to reset */ + default: + break; + } + + return SEPOL_OK; +} + +int cil_reset_ast(struct cil_tree_node *current) +{ + int rc = SEPOL_ERR; + + rc = cil_tree_walk(current, __cil_reset_node, NULL, NULL, NULL); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to reset AST\n"); + return SEPOL_ERR; + } + + return SEPOL_OK; +} diff --git a/kernel/libsepol/cil/src/cil_reset_ast.h b/kernel/libsepol/cil/src/cil_reset_ast.h new file mode 100644 index 00000000..393ff9ee --- /dev/null +++ b/kernel/libsepol/cil/src/cil_reset_ast.h @@ -0,0 +1,8 @@ +#ifndef CIL_RESET_AST_H_ +#define CIL_RESET_AST_H_ + +#include "cil_tree.h" + +int cil_reset_ast(struct cil_tree_node *current); + +#endif /* CIL_RESET_AST_H_ */ diff --git a/kernel/libsepol/cil/src/cil_resolve_ast.c b/kernel/libsepol/cil/src/cil_resolve_ast.c new file mode 100644 index 00000000..f5e22c97 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_resolve_ast.c @@ -0,0 +1,4479 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include + +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_build_ast.h" +#include "cil_resolve_ast.h" +#include "cil_reset_ast.h" +#include "cil_copy_ast.h" +#include "cil_verify.h" +#include "cil_strpool.h" +#include "cil_symtab.h" +#include "cil_stack.h" + +struct cil_args_resolve { + struct cil_db *db; + enum cil_pass pass; + uint32_t *changed; + struct cil_list *to_destroy; + struct cil_tree_node *block; + struct cil_tree_node *macro; + struct cil_tree_node *optional; + struct cil_tree_node *disabled_optional; + struct cil_tree_node *boolif; + struct cil_list *sidorder_lists; + struct cil_list *classorder_lists; + struct cil_list *unordered_classorder_lists; + struct cil_list *catorder_lists; + struct cil_list *sensitivityorder_lists; + struct cil_list *in_list_before; + struct cil_list *in_list_after; + struct cil_list *abstract_blocks; +}; + +static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node) +{ + /* Currently only used for typetransition file names. + But could be used for any string that is passed as a parameter. + */ + struct cil_tree_node *parent = ast_node->parent; + struct cil_macro *macro = NULL; + struct cil_name *name; + symtab_t *symtab; + enum cil_sym_index sym_index; + struct cil_symtab_datum *datum = NULL; + + if (parent->flavor == CIL_CALL) { + struct cil_call *call = parent->data; + macro = call->macro; + } else if (parent->flavor == CIL_MACRO) { + macro = parent->data; + } + if (macro != NULL && macro->params != NULL) { + struct cil_list_item *item; + cil_list_for_each(item, macro->params) { + struct cil_param *param = item->data; + if (param->flavor == CIL_NAME && param->str == key) { + return NULL; + } + } + } + + cil_flavor_to_symtab_index(CIL_NAME, &sym_index); + symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index]; + + cil_symtab_get_datum(symtab, key, &datum); + if (datum != NULL) { + return (struct cil_name *)datum; + } + + cil_name_init(&name); + cil_symtab_insert(symtab, key, (struct cil_symtab_datum *)name, ast_node); + cil_list_append(db->names, CIL_NAME, name); + + return name; +} + +static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, struct cil_list *perm_strs, struct cil_list **perm_datums, enum cil_flavor class_flavor) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + + cil_list_init(perm_datums, perm_strs->flavor); + + cil_list_for_each(curr, perm_strs) { + if (curr->flavor == CIL_LIST) { + struct cil_list *sub_list; + rc = __cil_resolve_perms(class_symtab, common_symtab, curr->data, &sub_list, class_flavor); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve permission list\n"); + goto exit; + } + cil_list_append(*perm_datums, CIL_LIST, sub_list); + } else if (curr->flavor == CIL_STRING) { + struct cil_symtab_datum *perm_datum = NULL; + rc = cil_symtab_get_datum(class_symtab, curr->data, &perm_datum); + if (rc == SEPOL_ENOENT) { + if (common_symtab) { + rc = cil_symtab_get_datum(common_symtab, curr->data, &perm_datum); + } + } + if (rc != SEPOL_OK) { + if (class_flavor == CIL_MAP_CLASS) { + cil_log(CIL_ERR, "Failed to resolve permission %s for map class\n", (char*)curr->data); + } else { + cil_log(CIL_ERR, "Failed to resolve permission %s\n", (char*)curr->data); + } + goto exit; + } + cil_list_append(*perm_datums, CIL_DATUM, perm_datum); + } else { + cil_list_append(*perm_datums, curr->flavor, curr->data); + } + } + + return SEPOL_OK; + +exit: + cil_list_destroy(perm_datums, CIL_FALSE); + return rc; +} + +int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_symtab_datum *datum = NULL; + symtab_t *common_symtab = NULL; + struct cil_class *class; + + if (cp->class) { + return SEPOL_OK; + } + + rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, extra_args, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + + class = (struct cil_class *)datum; + + if (class->common != NULL) { + common_symtab = &class->common->perms; + } + + cp->class = class; + + rc = __cil_resolve_perms(&class->perms, common_symtab, cp->perm_strs, &cp->perms, FLAVOR(datum)); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_classperms_set(struct cil_tree_node *current, struct cil_classperms_set *cp_set, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_symtab_datum *datum = NULL; + + rc = cil_resolve_name(current, cp_set->set_str, CIL_SYM_CLASSPERMSETS, extra_args, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + cp_set->set = (struct cil_classpermission*)datum; + + /* This could be an anonymous classpermission */ + if (datum->name == NULL) { + rc = cil_resolve_classperms_list(current, cp_set->set->classperms, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + + cil_list_for_each(curr, cp_list) { + if (curr->flavor == CIL_CLASSPERMS) { + rc = cil_resolve_classperms(current, curr->data, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } else { + rc = cil_resolve_classperms_set(current, curr->data, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_args_resolve *args = extra_args; + struct cil_list_item *curr; + struct cil_symtab_datum *datum; + struct cil_classpermission *cp; + + rc = cil_resolve_name(current, cps->set_str, CIL_SYM_CLASSPERMSETS, args, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_resolve_classperms_list(current, cps->classperms, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + cp = (struct cil_classpermission *)datum; + + if (cp->classperms == NULL) { + cil_list_init(&cp->classperms, CIL_CLASSPERMS); + } + + cil_list_for_each(curr, cps->classperms) { + cil_list_append(cp->classperms, curr->flavor, curr->data); + } + + return SEPOL_OK; + +exit: + return rc; +} + +static void cil_type_used(struct cil_symtab_datum *datum, int used) +{ + struct cil_typeattribute *attr = NULL; + + if (FLAVOR(datum) == CIL_TYPEATTRIBUTE) { + attr = (struct cil_typeattribute*)datum; + attr->used |= used; + if ((attr->used & CIL_ATTR_EXPAND_TRUE) && + (attr->used & CIL_ATTR_EXPAND_FALSE)) { + cil_log(CIL_WARN, "Conflicting use of expandtypeattribute. " + "Expandtypeattribute was set to both true or false for %s. " + "Resolving to false. \n", attr->datum.name); + attr->used &= ~CIL_ATTR_EXPAND_TRUE; + } + } +} + +static int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, void *extra_args) +{ + struct cil_symtab_datum *obj_datum = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); + if (rc != SEPOL_OK) { + goto exit; + } + permx->obj = (struct cil_class*)obj_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_db *db = NULL; + + struct cil_avrule *rule = current->data; + struct cil_symtab_datum *src_datum = NULL; + struct cil_symtab_datum *tgt_datum = NULL; + struct cil_symtab_datum *permx_datum = NULL; + int used; + int rc = SEPOL_ERR; + + if (args != NULL) { + db = args->db; + } + + rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, args, &src_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rule->src = src_datum; + + if (rule->tgt_str == CIL_KEY_SELF) { + rule->tgt = db->selftype; + } else { + rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rule->tgt = tgt_datum; + used = (rule->rule_kind == CIL_AVRULE_NEVERALLOW) ? + CIL_ATTR_NEVERALLOW : CIL_ATTR_AVRULE; + cil_type_used(src_datum, used); /* src not used if tgt is self */ + cil_type_used(tgt_datum, used); + } + + if (!rule->is_extended) { + rc = cil_resolve_classperms_list(current, rule->perms.classperms, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } else { + if (rule->perms.x.permx_str != NULL) { + rc = cil_resolve_name(current, rule->perms.x.permx_str, CIL_SYM_PERMX, args, &permx_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rule->perms.x.permx = (struct cil_permissionx*)permx_datum; + } else { + rc = cil_resolve_permissionx(current, rule->perms.x.permx, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_type_rule *rule = current->data; + struct cil_symtab_datum *src_datum = NULL; + struct cil_symtab_datum *tgt_datum = NULL; + struct cil_symtab_datum *obj_datum = NULL; + struct cil_symtab_datum *result_datum = NULL; + struct cil_tree_node *result_node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, extra_args, &src_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rule->src = src_datum; + + if (rule->tgt_str == CIL_KEY_SELF) { + rule->tgt = args->db->selftype; + } else { + rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rule->tgt = tgt_datum; + } + + rc = cil_resolve_name(current, rule->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rule->obj = (struct cil_class*)obj_datum; + + rc = cil_resolve_name(current, rule->result_str, CIL_SYM_TYPES, extra_args, &result_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + result_node = NODE(result_datum); + + if (result_node->flavor != CIL_TYPE) { + cil_log(CIL_ERR, "Type rule result must be a type [%d]\n",result_node->flavor); + rc = SEPOL_ERR; + goto exit; + } + rule->result = result_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args) +{ + struct cil_typeattributeset *attrtypes = current->data; + struct cil_symtab_datum *attr_datum = NULL; + struct cil_tree_node *attr_node = NULL; + struct cil_typeattribute *attr = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, attrtypes->attr_str, CIL_SYM_TYPES, extra_args, &attr_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + attr_node = NODE(attr_datum); + + if (attr_node->flavor != CIL_TYPEATTRIBUTE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Attribute type not an attribute\n"); + goto exit; + } + + attr = (struct cil_typeattribute*)attr_datum; + + rc = cil_resolve_expr(CIL_TYPEATTRIBUTESET, attrtypes->str_expr, &attrtypes->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + if (attr->expr_list == NULL) { + cil_list_init(&attr->expr_list, CIL_TYPEATTRIBUTE); + } + + cil_list_append(attr->expr_list, CIL_LIST, attrtypes->datum_expr); + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void *extra_args) +{ + struct cil_expandtypeattribute *expandattr = current->data; + struct cil_symtab_datum *attr_datum = NULL; + struct cil_tree_node *attr_node = NULL; + struct cil_list_item *curr; + int used; + int rc = SEPOL_ERR; + + cil_list_init(&expandattr->attr_datums, CIL_TYPE); + + cil_list_for_each(curr, expandattr->attr_strs) { + rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_TYPES, extra_args, &attr_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + attr_node = NODE(attr_datum); + + if (attr_node->flavor != CIL_TYPEATTRIBUTE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Attribute type not an attribute\n"); + goto exit; + } + used = expandattr->expand ? CIL_ATTR_EXPAND_TRUE : CIL_ATTR_EXPAND_FALSE; + cil_type_used(attr_datum, used); + cil_list_append(expandattr->attr_datums, CIL_TYPE, attr_datum); + } + + return SEPOL_OK; +exit: + return rc; +} + +static int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor alias_flavor) +{ + int rc = SEPOL_ERR; + enum cil_sym_index sym_index; + struct cil_aliasactual *aliasactual = current->data; + struct cil_symtab_datum *alias_datum = NULL; + struct cil_symtab_datum *actual_datum = NULL; + struct cil_alias *alias; + + rc = cil_flavor_to_symtab_index(flavor, &sym_index); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_resolve_name_keep_aliases(current, aliasactual->alias_str, sym_index, extra_args, &alias_datum); + if (rc != SEPOL_OK) { + goto exit; + } + if (FLAVOR(alias_datum) != alias_flavor) { + cil_log(CIL_ERR, "%s is not an alias\n",alias_datum->name); + rc = SEPOL_ERR; + goto exit; + } + + rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, extra_args, &actual_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + if (FLAVOR(actual_datum) != flavor && FLAVOR(actual_datum) != alias_flavor) { + cil_log(CIL_ERR, "%s is a %s, but aliases a %s\n", alias_datum->name, cil_node_to_string(NODE(alias_datum)), cil_node_to_string(NODE(actual_datum))); + rc = SEPOL_ERR; + goto exit; + } + + alias = (struct cil_alias *)alias_datum; + + if (alias->actual != NULL) { + cil_log(CIL_ERR, "%s %s cannot bind more than one value\n", cil_node_to_string(NODE(alias_datum)), alias_datum->name); + rc = SEPOL_ERR; + goto exit; + } + + alias->actual = actual_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor flavor) +{ + struct cil_alias *alias = current->data; + struct cil_alias *a1 = current->data; + struct cil_alias *a2 = current->data; + struct cil_tree_node *a1_node = NULL; + int steps = 0; + int limit = 2; + + if (alias->actual == NULL) { + cil_tree_log(current, CIL_ERR, "Alias declared but not used"); + return SEPOL_ERR; + } + + a1_node = a1->datum.nodes->head->data; + + while (flavor != a1_node->flavor) { + if (a1->actual == NULL) { + cil_tree_log(current, CIL_ERR, "Alias %s references an unused alias %s", alias->datum.name, a1->datum.name); + return SEPOL_ERR; + } + a1 = a1->actual; + a1_node = a1->datum.nodes->head->data; + steps += 1; + + if (a1 == a2) { + cil_log(CIL_ERR, "Circular alias found: %s ", a1->datum.name); + a1 = a1->actual; + while (a1 != a2) { + cil_log(CIL_ERR, "%s ", a1->datum.name); + a1 = a1->actual; + } + cil_log(CIL_ERR,"\n"); + return SEPOL_ERR; + } + + if (steps == limit) { + steps = 0; + limit *= 2; + a2 = a1; + } + } + + alias->actual = a1; + + return SEPOL_OK; +} + +int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args) +{ + struct cil_typepermissive *typeperm = current->data; + struct cil_symtab_datum *type_datum = NULL; + struct cil_tree_node *type_node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, typeperm->type_str, CIL_SYM_TYPES, extra_args, &type_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + type_node = NODE(type_datum); + + if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) { + cil_log(CIL_ERR, "Typepermissive must be a type or type alias\n"); + rc = SEPOL_ERR; + goto exit; + } + + typeperm->type = type_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_nametypetransition *nametypetrans = current->data; + struct cil_symtab_datum *src_datum = NULL; + struct cil_symtab_datum *tgt_datum = NULL; + struct cil_symtab_datum *obj_datum = NULL; + struct cil_symtab_datum *name_datum = NULL; + struct cil_symtab_datum *result_datum = NULL; + struct cil_tree_node *result_node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, nametypetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum); + if (rc != SEPOL_OK) { + goto exit; + } + nametypetrans->src = src_datum; + + if (nametypetrans->tgt_str == CIL_KEY_SELF) { + nametypetrans->tgt = args->db->selftype; + } else { + rc = cil_resolve_name(current, nametypetrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); + if (rc != SEPOL_OK) { + goto exit; + } + nametypetrans->tgt = tgt_datum; + } + + rc = cil_resolve_name(current, nametypetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); + if (rc != SEPOL_OK) { + goto exit; + } + nametypetrans->obj = (struct cil_class*)obj_datum; + + nametypetrans->name = __cil_insert_name(args->db, nametypetrans->name_str, current); + if (nametypetrans->name == NULL) { + rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_NAMES, extra_args, &name_datum); + if (rc != SEPOL_OK) { + goto exit; + } + nametypetrans->name = (struct cil_name *)name_datum; + } + + rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, extra_args, &result_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + result_node = NODE(result_datum); + + if (result_node->flavor != CIL_TYPE && result_node->flavor != CIL_TYPEALIAS) { + cil_log(CIL_ERR, "typetransition result is not a type or type alias\n"); + rc = SEPOL_ERR; + goto exit; + } + nametypetrans->result = result_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args) +{ + struct cil_rangetransition *rangetrans = current->data; + struct cil_symtab_datum *src_datum = NULL; + struct cil_symtab_datum *exec_datum = NULL; + struct cil_symtab_datum *obj_datum = NULL; + struct cil_symtab_datum *range_datum = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, rangetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rangetrans->src = src_datum; + + rc = cil_resolve_name(current, rangetrans->exec_str, CIL_SYM_TYPES, extra_args, &exec_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rangetrans->exec = exec_datum; + + rc = cil_resolve_name(current, rangetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rangetrans->obj = (struct cil_class*)obj_datum; + + if (rangetrans->range_str != NULL) { + rc = cil_resolve_name(current, rangetrans->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum); + if (rc != SEPOL_OK) { + goto exit; + } + rangetrans->range = (struct cil_levelrange*)range_datum; + + /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/ + if (rangetrans->range->datum.name == NULL) { + rc = cil_resolve_levelrange(current, rangetrans->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else { + rc = cil_resolve_levelrange(current, rangetrans->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __class_update_perm_values(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct cil_perm *perm = (struct cil_perm *)d; + + perm->value += *((int *)args); + + return SEPOL_OK; +} + +int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_class *class = NULL; + struct cil_class *common = NULL; + struct cil_classcommon *clscom = current->data; + struct cil_symtab_datum *class_datum = NULL; + struct cil_symtab_datum *common_datum = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, clscom->class_str, CIL_SYM_CLASSES, extra_args, &class_datum); + if (rc != SEPOL_OK) { + goto exit; + } + if (NODE(class_datum)->flavor != CIL_CLASS) { + cil_log(CIL_ERR, "Class %s is not a kernel class and cannot be associated with common %s\n", clscom->class_str, clscom->common_str); + rc = SEPOL_ERR; + goto exit; + } + + rc = cil_resolve_name(current, clscom->common_str, CIL_SYM_COMMONS, extra_args, &common_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + class = (struct cil_class *)class_datum; + common = (struct cil_class *)common_datum; + if (class->common != NULL) { + cil_log(CIL_ERR, "class cannot be associeated with more than one common\n"); + rc = SEPOL_ERR; + goto exit; + } + + class->common = common; + + cil_symtab_map(&class->perms, __class_update_perm_values, &common->num_perms); + + class->num_perms += common->num_perms; + if (class->num_perms > CIL_PERMS_PER_CLASS) { + cil_tree_log(current, CIL_ERR, "Too many permissions in class '%s' when including common permissions", class->datum.name); + rc = SEPOL_ERR; + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_classmapping *mapping = current->data; + struct cil_class *map = NULL; + struct cil_perm *mp = NULL; + struct cil_symtab_datum *datum = NULL; + struct cil_list_item *curr; + + rc = cil_resolve_name(current, mapping->map_class_str, CIL_SYM_CLASSES, extra_args, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + map = (struct cil_class*)datum; + + rc = cil_symtab_get_datum(&map->perms, mapping->map_perm_str, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + + mp = (struct cil_perm*)datum; + + rc = cil_resolve_classperms_list(current, mapping->classperms, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + if (mp->classperms == NULL) { + cil_list_init(&mp->classperms, CIL_CLASSPERMS); + } + + cil_list_for_each(curr, mapping->classperms) { + cil_list_append(mp->classperms, curr->flavor, curr->data); + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_userrole(struct cil_tree_node *current, void *extra_args) +{ + struct cil_userrole *userrole = current->data; + struct cil_symtab_datum *user_datum = NULL; + struct cil_symtab_datum *role_datum = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, userrole->user_str, CIL_SYM_USERS, extra_args, &user_datum); + if (rc != SEPOL_OK) { + goto exit; + } + userrole->user = (struct cil_user*)user_datum; + + rc = cil_resolve_name(current, userrole->role_str, CIL_SYM_ROLES, extra_args, &role_datum); + if (rc != SEPOL_OK) { + goto exit; + } + userrole->role = role_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args) +{ + struct cil_userlevel *usrlvl = current->data; + struct cil_symtab_datum *user_datum = NULL; + struct cil_symtab_datum *lvl_datum = NULL; + struct cil_user *user = NULL; + struct cil_tree_node *user_node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, extra_args, &user_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + user_node = NODE(user_datum); + + if (user_node->flavor != CIL_USER) { + cil_log(CIL_ERR, "Userlevel must be a user\n"); + rc = SEPOL_ERR; + goto exit; + } + + user = (struct cil_user*)user_datum; + + if (usrlvl->level_str != NULL) { + rc = cil_resolve_name(current, usrlvl->level_str, CIL_SYM_LEVELS, extra_args, &lvl_datum); + if (rc != SEPOL_OK) { + goto exit; + } + usrlvl->level = (struct cil_level*)lvl_datum; + user->dftlevel = usrlvl->level; + + /* This could still be an anonymous level even if level_str is set, if level_str is a param_str*/ + if (user->dftlevel->datum.name == NULL) { + rc = cil_resolve_level(current, user->dftlevel, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else if (usrlvl->level != NULL) { + rc = cil_resolve_level(current, usrlvl->level, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + user->dftlevel = usrlvl->level; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args) +{ + struct cil_userrange *userrange = current->data; + struct cil_symtab_datum *user_datum = NULL; + struct cil_symtab_datum *range_datum = NULL; + struct cil_user *user = NULL; + struct cil_tree_node *user_node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, extra_args, &user_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + user_node = NODE(user_datum); + + if (user_node->flavor != CIL_USER) { + cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn); + rc = SEPOL_ERR; + goto exit; + } + + user = (struct cil_user*)user_datum; + + if (userrange->range_str != NULL) { + rc = cil_resolve_name(current, userrange->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum); + if (rc != SEPOL_OK) { + goto exit; + } + userrange->range = (struct cil_levelrange*)range_datum; + user->range = userrange->range; + + /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/ + if (user->range->datum.name == NULL) { + rc = cil_resolve_levelrange(current, user->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else if (userrange->range != NULL) { + rc = cil_resolve_levelrange(current, userrange->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + user->range = userrange->range; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args) +{ + struct cil_userprefix *userprefix = current->data; + struct cil_symtab_datum *user_datum = NULL; + struct cil_tree_node *user_node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, extra_args, &user_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + user_node = NODE(user_datum); + + if (user_node->flavor != CIL_USER) { + cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn); + rc = SEPOL_ERR; + goto exit; + } + + userprefix->user = (struct cil_user*)user_datum; + +exit: + return rc; +} + +int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args) +{ + struct cil_selinuxuser *selinuxuser = current->data; + struct cil_symtab_datum *user_datum = NULL; + struct cil_symtab_datum *lvlrange_datum = NULL; + struct cil_tree_node *user_node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, extra_args, &user_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + user_node = NODE(user_datum); + + if (user_node->flavor != CIL_USER) { + cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn); + rc = SEPOL_ERR; + goto exit; + } + + selinuxuser->user = (struct cil_user*)user_datum; + + if (selinuxuser->range_str != NULL) { + rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum); + if (rc != SEPOL_OK) { + goto exit; + } + selinuxuser->range = (struct cil_levelrange*)lvlrange_datum; + + /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/ + if (selinuxuser->range->datum.name == NULL) { + rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else if (selinuxuser->range != NULL) { + rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + rc = SEPOL_OK; +exit: + return rc; +} + +int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args) +{ + struct cil_roletype *roletype = current->data; + struct cil_symtab_datum *role_datum = NULL; + struct cil_symtab_datum *type_datum = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, roletype->role_str, CIL_SYM_ROLES, extra_args, &role_datum); + if (rc != SEPOL_OK) { + goto exit; + } + roletype->role = (struct cil_role*)role_datum; + + rc = cil_resolve_name(current, roletype->type_str, CIL_SYM_TYPES, extra_args, &type_datum); + if (rc != SEPOL_OK) { + goto exit; + } + roletype->type = (struct cil_type*)type_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args) +{ + struct cil_roletransition *roletrans = current->data; + struct cil_symtab_datum *src_datum = NULL; + struct cil_symtab_datum *tgt_datum = NULL; + struct cil_symtab_datum *obj_datum = NULL; + struct cil_symtab_datum *result_datum = NULL; + struct cil_tree_node *node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, roletrans->src_str, CIL_SYM_ROLES, extra_args, &src_datum); + if (rc != SEPOL_OK) { + goto exit; + } + roletrans->src = (struct cil_role*)src_datum; + + rc = cil_resolve_name(current, roletrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); + if (rc != SEPOL_OK) { + goto exit; + } + roletrans->tgt = tgt_datum; + + rc = cil_resolve_name(current, roletrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); + if (rc != SEPOL_OK) { + goto exit; + } + roletrans->obj = (struct cil_class*)obj_datum; + + rc = cil_resolve_name(current, roletrans->result_str, CIL_SYM_ROLES, extra_args, &result_datum); + if (rc != SEPOL_OK) { + goto exit; + } + node = NODE(result_datum); + if (node->flavor != CIL_ROLE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "roletransition must result in a role, but %s is a %s\n", roletrans->result_str, cil_node_to_string(node)); + goto exit; + } + roletrans->result = (struct cil_role*)result_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_roleallow(struct cil_tree_node *current, void *extra_args) +{ + struct cil_roleallow *roleallow = current->data; + struct cil_symtab_datum *src_datum = NULL; + struct cil_symtab_datum *tgt_datum = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, roleallow->src_str, CIL_SYM_ROLES, extra_args, &src_datum); + if (rc != SEPOL_OK) { + goto exit; + } + roleallow->src = (struct cil_role*)src_datum; + + rc = cil_resolve_name(current, roleallow->tgt_str, CIL_SYM_ROLES, extra_args, &tgt_datum); + if (rc != SEPOL_OK) { + goto exit; + } + roleallow->tgt = (struct cil_role*)tgt_datum; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_roleattributeset *attrroles = current->data; + struct cil_symtab_datum *attr_datum = NULL; + struct cil_tree_node *attr_node = NULL; + struct cil_roleattribute *attr = NULL; + + rc = cil_resolve_name(current, attrroles->attr_str, CIL_SYM_ROLES, extra_args, &attr_datum); + if (rc != SEPOL_OK) { + goto exit; + } + attr_node = NODE(attr_datum); + + if (attr_node->flavor != CIL_ROLEATTRIBUTE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Attribute role not an attribute\n"); + goto exit; + } + attr = (struct cil_roleattribute*)attr_datum; + + rc = cil_resolve_expr(CIL_ROLEATTRIBUTESET, attrroles->str_expr, &attrroles->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + if (attr->expr_list == NULL) { + cil_list_init(&attr->expr_list, CIL_ROLEATTRIBUTE); + } + + cil_list_append(attr->expr_list, CIL_LIST, attrroles->datum_expr); + + return SEPOL_OK; + +exit: + return rc; +} + +struct cil_ordered_list { + int merged; + struct cil_list *list; + struct cil_tree_node *node; +}; + +static void __cil_ordered_list_init(struct cil_ordered_list **ordered) +{ + *ordered = cil_malloc(sizeof(**ordered)); + + (*ordered)->merged = CIL_FALSE; + (*ordered)->list = NULL; + (*ordered)->node = NULL; +} + +static void __cil_ordered_list_destroy(struct cil_ordered_list **ordered) +{ + cil_list_destroy(&(*ordered)->list, CIL_FALSE); + (*ordered)->node = NULL; + free(*ordered); + *ordered = NULL; +} + +static void __cil_ordered_lists_destroy(struct cil_list **ordered_lists) +{ + struct cil_list_item *item = NULL; + + if (ordered_lists == NULL || *ordered_lists == NULL) { + return; + } + + item = (*ordered_lists)->head; + while (item != NULL) { + struct cil_list_item *next = item->next; + struct cil_ordered_list *ordered = item->data; + __cil_ordered_list_destroy(&ordered); + free(item); + item = next; + } + free(*ordered_lists); + *ordered_lists = NULL; +} + +static void __cil_ordered_lists_reset(struct cil_list **ordered_lists) +{ + __cil_ordered_lists_destroy(ordered_lists); + cil_list_init(ordered_lists, CIL_LIST_ITEM); +} + +static struct cil_list_item *__cil_ordered_item_insert(struct cil_list *old, struct cil_list_item *curr, struct cil_list_item *item) +{ + if (item->flavor == CIL_SID) { + struct cil_sid *sid = item->data; + if (sid->ordered == CIL_TRUE) { + cil_log(CIL_ERR, "SID %s has already been merged into the ordered list\n", sid->datum.name); + return NULL; + } + sid->ordered = CIL_TRUE; + } else if (item->flavor == CIL_CLASS) { + struct cil_class *class = item->data; + if (class->ordered == CIL_TRUE) { + cil_log(CIL_ERR, "Class %s has already been merged into the ordered list\n", class->datum.name); + return NULL; + } + class->ordered = CIL_TRUE; + } else if (item->flavor == CIL_CAT) { + struct cil_cat *cat = item->data; + if (cat->ordered == CIL_TRUE) { + cil_log(CIL_ERR, "Category %s has already been merged into the ordered list\n", cat->datum.name); + return NULL; + } + cat->ordered = CIL_TRUE; + } else if (item->flavor == CIL_SENS) { + struct cil_sens *sens = item->data; + if (sens->ordered == CIL_TRUE) { + cil_log(CIL_ERR, "Sensitivity %s has already been merged into the ordered list\n", sens->datum.name); + return NULL; + } + sens->ordered = CIL_TRUE; + } + + return cil_list_insert(old, curr, item->flavor, item->data); +} + +static int __cil_ordered_list_insert(struct cil_list *old, struct cil_list_item *ocurr, struct cil_list_item *nstart, struct cil_list_item *nstop) +{ + struct cil_list_item *ncurr = NULL; + + for (ncurr = nstart; ncurr != nstop; ncurr = ncurr->next) { + ocurr = __cil_ordered_item_insert(old, ocurr, ncurr); + if (ocurr == NULL) { + return SEPOL_ERR; + } + } + return SEPOL_OK; +} + +static struct cil_list_item *__cil_ordered_find_match(struct cil_list_item *t, struct cil_list_item *i) +{ + while (i) { + if (i->data == t->data) { + return i; + } + i = i->next; + } + return NULL; +} + +static int __cil_ordered_lists_merge(struct cil_list *old, struct cil_list *new) +{ + struct cil_list_item *omatch = NULL; + struct cil_list_item *ofirst = old->head; + struct cil_list_item *ocurr = NULL; + struct cil_list_item *oprev = NULL; + struct cil_list_item *nmatch = NULL; + struct cil_list_item *nfirst = new->head; + struct cil_list_item *ncurr = NULL; + int rc = SEPOL_ERR; + + if (nfirst == NULL) { + return SEPOL_OK; + } + + if (ofirst == NULL) { + /* First list added */ + rc = __cil_ordered_list_insert(old, NULL, nfirst, NULL); + return rc; + } + + /* Find a match between the new list and the old one */ + for (nmatch = nfirst; nmatch; nmatch = nmatch->next) { + omatch = __cil_ordered_find_match(nmatch, ofirst); + if (omatch) { + break; + } + } + + if (!nmatch) { + /* List cannot be merged yet */ + return SEPOL_ERR; + } + + if (nmatch != nfirst && omatch != ofirst) { + /* Potential ordering conflict--try again later */ + return SEPOL_ERR; + } + + if (nmatch != nfirst) { + /* Prepend the beginning of the new list up to the first match to the old list */ + rc = __cil_ordered_list_insert(old, NULL, nfirst, nmatch); + if (rc != SEPOL_OK) { + return rc; + } + } + + /* In the overlapping protion, add items from the new list not in the old list */ + ncurr = nmatch->next; + ocurr = omatch->next; + oprev = omatch; + while (ncurr && ocurr) { + if (ncurr->data == ocurr->data) { + oprev = ocurr; + ocurr = ocurr->next; + ncurr = ncurr->next; + } else { + /* Handle gap in old: old = (A C) new = (A B C) */ + nmatch = __cil_ordered_find_match(ocurr, ncurr->next); + if (nmatch) { + rc = __cil_ordered_list_insert(old, oprev, ncurr, nmatch); + if (rc != SEPOL_OK) { + return rc; + } + oprev = ocurr; + ocurr = ocurr->next; + ncurr = nmatch->next; + continue; + } + /* Handle gap in new: old = (A B C) new = (A C) */ + omatch = __cil_ordered_find_match(ncurr, ocurr->next); + if (omatch) { + /* Nothing to insert, just skip */ + oprev = omatch; + ocurr = omatch->next; + ncurr = ncurr->next; + continue; + } else { + return SEPOL_ERR; + } + } + } + + if (ncurr) { + /* Add the rest of the items from the new list */ + rc = __cil_ordered_list_insert(old, old->tail, ncurr, NULL); + if (rc != SEPOL_OK) { + return rc; + } + } + + return SEPOL_OK; +} + +static int insert_unordered(struct cil_list *merged, struct cil_list *unordered) +{ + struct cil_list_item *curr = NULL; + struct cil_ordered_list *unordered_list = NULL; + struct cil_list_item *item = NULL; + struct cil_list_item *ret = NULL; + int rc = SEPOL_ERR; + + cil_list_for_each(curr, unordered) { + unordered_list = curr->data; + + cil_list_for_each(item, unordered_list->list) { + if (cil_list_contains(merged, item->data)) { + /* item was declared in an ordered statement, which supersedes + * all unordered statements */ + if (item->flavor == CIL_CLASS) { + cil_log(CIL_WARN, "Ignoring '%s' as it has already been declared in classorder.\n", ((struct cil_class*)(item->data))->datum.name); + } + continue; + } + + ret = __cil_ordered_item_insert(merged, merged->tail, item); + if (ret == NULL) { + rc = SEPOL_ERR; + goto exit; + } + } + } + + rc = SEPOL_OK; + +exit: + return rc; +} + +static struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists, struct cil_list **unordered_lists) +{ + struct cil_list *composite = NULL; + struct cil_list_item *curr = NULL; + int changed = CIL_TRUE; + int waiting = 1; + int rc = SEPOL_ERR; + + cil_list_init(&composite, CIL_LIST_ITEM); + + while (waiting && changed == CIL_TRUE) { + changed = CIL_FALSE; + waiting = 0; + cil_list_for_each(curr, *ordered_lists) { + struct cil_ordered_list *ordered_list = curr->data; + if (ordered_list->merged == CIL_FALSE) { + rc = __cil_ordered_lists_merge(composite, ordered_list->list); + if (rc != SEPOL_OK) { + /* Can't merge yet */ + waiting++; + } else { + ordered_list->merged = CIL_TRUE; + changed = CIL_TRUE; + } + } + } + if (waiting > 0 && changed == CIL_FALSE) { + cil_list_for_each(curr, *ordered_lists) { + struct cil_ordered_list *ordered_list = curr->data; + if (ordered_list->merged == CIL_FALSE) { + cil_tree_log(ordered_list->node, CIL_ERR, "Unable to merge ordered list"); + } + } + goto exit; + } + } + + if (unordered_lists != NULL) { + rc = insert_unordered(composite, *unordered_lists); + if (rc != SEPOL_OK) { + goto exit; + } + } + + __cil_ordered_lists_destroy(ordered_lists); + __cil_ordered_lists_destroy(unordered_lists); + + return composite; + +exit: + __cil_ordered_lists_destroy(ordered_lists); + __cil_ordered_lists_destroy(unordered_lists); + cil_list_destroy(&composite, CIL_FALSE); + return NULL; +} + +int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_list *classorder_list = args->classorder_lists; + struct cil_list *unordered_classorder_list = args->unordered_classorder_lists; + struct cil_classorder *classorder = current->data; + struct cil_list *new = NULL; + struct cil_list_item *curr = NULL; + struct cil_symtab_datum *datum = NULL; + struct cil_ordered_list *class_list = NULL; + int rc = SEPOL_ERR; + int unordered = CIL_FALSE; + + cil_list_init(&new, CIL_CLASSORDER); + + cil_list_for_each(curr, classorder->class_list_str) { + if (curr->data == CIL_KEY_UNORDERED) { + unordered = CIL_TRUE; + continue; + } + + rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve class %s in classorder\n", (char *)curr->data); + rc = SEPOL_ERR; + goto exit; + } + if (FLAVOR(datum) != CIL_CLASS) { + cil_log(CIL_ERR, "%s is not a class. Only classes are allowed in classorder statements\n", datum->name); + rc = SEPOL_ERR; + goto exit; + } + cil_list_append(new, CIL_CLASS, datum); + } + + __cil_ordered_list_init(&class_list); + class_list->list = new; + class_list->node = current; + if (unordered) { + cil_list_append(unordered_classorder_list, CIL_CLASSORDER, class_list); + } else { + cil_list_append(classorder_list, CIL_CLASSORDER, class_list); + } + + return SEPOL_OK; + +exit: + cil_list_destroy(&new, CIL_FALSE); + return rc; +} + +int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_list *sidorder_list = args->sidorder_lists; + struct cil_sidorder *sidorder = current->data; + struct cil_list *new = NULL; + struct cil_list_item *curr = NULL; + struct cil_symtab_datum *datum = NULL; + struct cil_ordered_list *ordered = NULL; + int rc = SEPOL_ERR; + + cil_list_init(&new, CIL_SIDORDER); + + cil_list_for_each(curr, sidorder->sid_list_str) { + rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SIDS, extra_args, &datum); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data); + goto exit; + } + if (FLAVOR(datum) != CIL_SID) { + cil_log(CIL_ERR, "%s is not a sid. Only sids are allowed in sidorder statements\n", datum->name); + rc = SEPOL_ERR; + goto exit; + } + + cil_list_append(new, CIL_SID, datum); + } + + __cil_ordered_list_init(&ordered); + ordered->list = new; + ordered->node = current; + cil_list_append(sidorder_list, CIL_SIDORDER, ordered); + + return SEPOL_OK; + +exit: + cil_list_destroy(&new, CIL_FALSE); + return rc; +} + +static void cil_set_cat_values(struct cil_list *ordered_cats, struct cil_db *db) +{ + struct cil_list_item *curr; + int v = 0; + + cil_list_for_each(curr, ordered_cats) { + struct cil_cat *cat = curr->data; + cat->value = v; + v++; + } + + db->num_cats = v; +} + +int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_list *catorder_list = args->catorder_lists; + struct cil_catorder *catorder = current->data; + struct cil_list *new = NULL; + struct cil_list_item *curr = NULL; + struct cil_symtab_datum *cat_datum; + struct cil_cat *cat = NULL; + struct cil_ordered_list *ordered = NULL; + int rc = SEPOL_ERR; + + cil_list_init(&new, CIL_CATORDER); + + cil_list_for_each(curr, catorder->cat_list_str) { + struct cil_tree_node *node = NULL; + rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, extra_args, &cat_datum); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data); + goto exit; + } + node = NODE(cat_datum); + if (node->flavor != CIL_CAT) { + cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", cat_datum->name); + rc = SEPOL_ERR; + goto exit; + } + cat = (struct cil_cat *)cat_datum; + cil_list_append(new, CIL_CAT, cat); + } + + __cil_ordered_list_init(&ordered); + ordered->list = new; + ordered->node = current; + cil_list_append(catorder_list, CIL_CATORDER, ordered); + + return SEPOL_OK; + +exit: + cil_list_destroy(&new, CIL_FALSE); + return rc; +} + +int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_list *sensitivityorder_list = args->sensitivityorder_lists; + struct cil_sensorder *sensorder = current->data; + struct cil_list *new = NULL; + struct cil_list_item *curr = NULL; + struct cil_symtab_datum *datum = NULL; + struct cil_ordered_list *ordered = NULL; + int rc = SEPOL_ERR; + + cil_list_init(&new, CIL_LIST_ITEM); + + cil_list_for_each(curr, sensorder->sens_list_str) { + rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, extra_args, &datum); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to resolve sensitivity %s in sensitivityorder\n", (char *)curr->data); + goto exit; + } + if (FLAVOR(datum) != CIL_SENS) { + cil_log(CIL_ERR, "%s is not a sensitivity. Only sensitivities are allowed in sensitivityorder statements\n", datum->name); + rc = SEPOL_ERR; + goto exit; + } + cil_list_append(new, CIL_SENS, datum); + } + + __cil_ordered_list_init(&ordered); + ordered->list = new; + ordered->node = current; + cil_list_append(sensitivityorder_list, CIL_SENSITIVITYORDER, ordered); + + return SEPOL_OK; + +exit: + cil_list_destroy(&new, CIL_FALSE); + return rc; +} + +static int cil_resolve_cats(struct cil_tree_node *current, struct cil_cats *cats, void *extra_args) +{ + int rc = SEPOL_ERR; + + rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + + +int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args) +{ + return cil_resolve_cats(current, catset->cats, extra_args); +} + +int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_senscat *senscat = current->data; + struct cil_symtab_datum *sens_datum; + struct cil_sens *sens = NULL; + + rc = cil_resolve_name(current, (char*)senscat->sens_str, CIL_SYM_SENS, extra_args, &sens_datum); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to find sensitivity\n"); + goto exit; + } + + rc = cil_resolve_cats(current, senscat->cats, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + sens = (struct cil_sens *)sens_datum; + + if (sens->cats_list == NULL ) { + cil_list_init(&sens->cats_list, CIL_CAT); + } + + cil_list_append(sens->cats_list, CIL_CAT, senscat->cats); + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, void *extra_args) +{ + struct cil_symtab_datum *sens_datum = NULL; + int rc = SEPOL_ERR; + + if (level->sens) { + return SEPOL_OK; + } + + rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, extra_args, &sens_datum); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to find sensitivity\n"); + goto exit; + } + + level->sens = (struct cil_sens *)sens_datum; + + if (level->cats != NULL) { + rc = cil_resolve_cats(current, level->cats, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *lvlrange, void *extra_args) +{ + struct cil_symtab_datum *low_datum = NULL; + struct cil_symtab_datum *high_datum = NULL; + int rc = SEPOL_ERR; + + if (lvlrange->low_str != NULL) { + rc = cil_resolve_name(current, lvlrange->low_str, CIL_SYM_LEVELS, extra_args, &low_datum); + if (rc != SEPOL_OK) { + goto exit; + } + lvlrange->low = (struct cil_level*)low_datum; + + /* This could still be an anonymous level even if low_str is set, if low_str is a param_str */ + if (lvlrange->low->datum.name == NULL) { + rc = cil_resolve_level(current, lvlrange->low, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else if (lvlrange->low != NULL) { + rc = cil_resolve_level(current, lvlrange->low, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (lvlrange->high_str != NULL) { + rc = cil_resolve_name(current, lvlrange->high_str, CIL_SYM_LEVELS, extra_args, &high_datum); + if (rc != SEPOL_OK) { + goto exit; + } + lvlrange->high = (struct cil_level*)high_datum; + + /* This could still be an anonymous level even if high_str is set, if high_str is a param_str */ + if (lvlrange->high->datum.name == NULL) { + rc = cil_resolve_level(current, lvlrange->high, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else if (lvlrange->high != NULL) { + rc = cil_resolve_level(current, lvlrange->high, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_constrain(struct cil_tree_node *current, void *extra_args) +{ + struct cil_constrain *cons = current->data; + int rc = SEPOL_ERR; + + rc = cil_resolve_classperms_list(current, cons->classperms, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_resolve_expr(CIL_CONSTRAIN, cons->str_expr, &cons->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_validatetrans(struct cil_tree_node *current, void *extra_args) +{ + struct cil_validatetrans *validtrans = current->data; + struct cil_args_resolve *args = extra_args; + struct cil_symtab_datum *class_datum = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, validtrans->class_str, CIL_SYM_CLASSES, args, &class_datum); + if (rc != SEPOL_OK) { + goto exit; + } + validtrans->class = (struct cil_class*)class_datum; + + rc = cil_resolve_expr(CIL_VALIDATETRANS, validtrans->str_expr, &validtrans->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, void *extra_args) +{ + struct cil_symtab_datum *user_datum = NULL; + struct cil_symtab_datum *role_datum = NULL; + struct cil_symtab_datum *type_datum = NULL; + struct cil_tree_node *node = NULL; + struct cil_symtab_datum *lvlrange_datum = NULL; + + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, extra_args, &user_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + node = NODE(user_datum); + + if (node->flavor != CIL_USER) { + cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn); + rc = SEPOL_ERR; + goto exit; + } + + context->user = (struct cil_user*)user_datum; + + rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, extra_args, &role_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + node = NODE(role_datum); + if (node->flavor != CIL_ROLE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn); + goto exit; + } + + context->role = (struct cil_role*)role_datum; + + rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, extra_args, &type_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + node = NODE(type_datum); + + if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Type not a type or type alias\n"); + goto exit; + } + context->type = type_datum; + + if (context->range_str != NULL) { + rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum); + if (rc != SEPOL_OK) { + goto exit; + } + context->range = (struct cil_levelrange*)lvlrange_datum; + + /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/ + if (context->range->datum.name == NULL) { + rc = cil_resolve_levelrange(current, context->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else if (context->range != NULL) { + rc = cil_resolve_levelrange(current, context->range, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_filecon *filecon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (filecon->context_str != NULL) { + rc = cil_resolve_name(current, filecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + return rc; + } + filecon->context = (struct cil_context*)context_datum; + } else if (filecon->context != NULL) { + rc = cil_resolve_context(current, filecon->context, extra_args); + if (rc != SEPOL_OK) { + return rc; + } + } + + return SEPOL_OK; +} + +int cil_resolve_ibpkeycon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_ibpkeycon *ibpkeycon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (ibpkeycon->context_str) { + rc = cil_resolve_name(current, ibpkeycon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) + goto exit; + + ibpkeycon->context = (struct cil_context *)context_datum; + } else { + rc = cil_resolve_context(current, ibpkeycon->context, extra_args); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_portcon *portcon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (portcon->context_str != NULL) { + rc = cil_resolve_name(current, portcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + portcon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, portcon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_genfscon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_genfscon *genfscon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (genfscon->context_str != NULL) { + rc = cil_resolve_name(current, genfscon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + genfscon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, genfscon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_nodecon *nodecon = current->data; + struct cil_symtab_datum *addr_datum = NULL; + struct cil_symtab_datum *mask_datum = NULL; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (nodecon->addr_str != NULL) { + rc = cil_resolve_name(current, nodecon->addr_str, CIL_SYM_IPADDRS, extra_args, &addr_datum); + if (rc != SEPOL_OK) { + goto exit; + } + nodecon->addr = (struct cil_ipaddr*)addr_datum; + } + + if (nodecon->mask_str != NULL) { + rc = cil_resolve_name(current, nodecon->mask_str, CIL_SYM_IPADDRS, extra_args, &mask_datum); + if (rc != SEPOL_OK) { + goto exit; + } + nodecon->mask = (struct cil_ipaddr*)mask_datum; + } + + if (nodecon->context_str != NULL) { + rc = cil_resolve_name(current, nodecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + nodecon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, nodecon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (nodecon->addr->family != nodecon->mask->family) { + cil_log(CIL_ERR, "Nodecon ip address not in the same family\n"); + rc = SEPOL_ERR; + goto exit; + } + + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_netifcon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_netifcon *netifcon = current->data; + struct cil_symtab_datum *ifcon_datum = NULL; + struct cil_symtab_datum *packcon_datum = NULL; + + int rc = SEPOL_ERR; + + if (netifcon->if_context_str != NULL) { + rc = cil_resolve_name(current, netifcon->if_context_str, CIL_SYM_CONTEXTS, extra_args, &ifcon_datum); + if (rc != SEPOL_OK) { + goto exit; + } + netifcon->if_context = (struct cil_context*)ifcon_datum; + } else { + rc = cil_resolve_context(current, netifcon->if_context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (netifcon->packet_context_str != NULL) { + rc = cil_resolve_name(current, netifcon->packet_context_str, CIL_SYM_CONTEXTS, extra_args, &packcon_datum); + if (rc != SEPOL_OK) { + goto exit; + } + netifcon->packet_context = (struct cil_context*)packcon_datum; + } else { + rc = cil_resolve_context(current, netifcon->packet_context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_ibendportcon *ibendportcon = current->data; + struct cil_symtab_datum *con_datum = NULL; + + int rc = SEPOL_ERR; + + if (ibendportcon->context_str) { + rc = cil_resolve_name(current, ibendportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &con_datum); + if (rc != SEPOL_OK) + goto exit; + + ibendportcon->context = (struct cil_context *)con_datum; + } else { + rc = cil_resolve_context(current, ibendportcon->context, extra_args); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_pirqcon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_pirqcon *pirqcon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (pirqcon->context_str != NULL) { + rc = cil_resolve_name(current, pirqcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + pirqcon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, pirqcon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_iomemcon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_iomemcon *iomemcon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (iomemcon->context_str != NULL) { + rc = cil_resolve_name(current, iomemcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + iomemcon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, iomemcon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_ioportcon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_ioportcon *ioportcon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (ioportcon->context_str != NULL) { + rc = cil_resolve_name(current, ioportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + ioportcon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, ioportcon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_pcidevicecon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_pcidevicecon *pcidevicecon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (pcidevicecon->context_str != NULL) { + rc = cil_resolve_name(current, pcidevicecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + pcidevicecon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, pcidevicecon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_devicetreecon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_devicetreecon *devicetreecon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (devicetreecon->context_str != NULL) { + rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + devicetreecon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, devicetreecon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args) +{ + struct cil_fsuse *fsuse = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (fsuse->context_str != NULL) { + rc = cil_resolve_name(current, fsuse->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + fsuse->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, fsuse->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_sidcontext(struct cil_tree_node *current, void *extra_args) +{ + struct cil_sidcontext *sidcon = current->data; + struct cil_symtab_datum *sid_datum = NULL; + struct cil_symtab_datum *context_datum = NULL; + struct cil_sid *sid = NULL; + + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, sidcon->sid_str, CIL_SYM_SIDS, extra_args, &sid_datum); + if (rc != SEPOL_OK) { + goto exit; + } + sid = (struct cil_sid*)sid_datum; + + if (sidcon->context_str != NULL) { + rc = cil_resolve_name(current, sidcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + sidcon->context = (struct cil_context*)context_datum; + } else if (sidcon->context != NULL) { + rc = cil_resolve_context(current, sidcon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (sid->context != NULL) { + cil_log(CIL_ERR, "sid's cannot be associated with more than one context\n"); + rc = SEPOL_ERR; + goto exit; + } + + sid->context = sidcon->context; + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_args) +{ + struct cil_blockinherit *inherit = current->data; + struct cil_symtab_datum *block_datum = NULL; + struct cil_tree_node *node = NULL; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + node = NODE(block_datum); + + if (node->flavor != CIL_BLOCK) { + cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node)); + rc = SEPOL_ERR; + goto exit; + } + + inherit->block = (struct cil_block *)block_datum; + + if (inherit->block->bi_nodes == NULL) { + cil_list_init(&inherit->block->bi_nodes, CIL_NODE); + } + cil_list_append(inherit->block->bi_nodes, CIL_NODE, current); + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args) +{ + struct cil_block *block = current->data; + struct cil_args_resolve *args = extra_args; + struct cil_db *db = NULL; + struct cil_list_item *item = NULL; + int rc = SEPOL_ERR; + + // This block is not inherited + if (block->bi_nodes == NULL) { + rc = SEPOL_OK; + goto exit; + } + + db = args->db; + + // Make sure this is the original block and not a merged block from a blockinherit + if (current != block->datum.nodes->head->data) { + rc = SEPOL_OK; + goto exit; + } + + cil_list_for_each(item, block->bi_nodes) { + rc = cil_copy_ast(db, current, item->data); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n"); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static void cil_mark_subtree_abstract(struct cil_tree_node *node) +{ + struct cil_block *block = node->data; + + block->is_abstract = CIL_TRUE; + + for (node = node->cl_head; node; node = node->next) { + if (node->flavor == CIL_BLOCK) { + cil_mark_subtree_abstract(node); + } + } +} + +static int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args) +{ + struct cil_blockabstract *abstract = current->data; + struct cil_symtab_datum *block_datum = NULL; + struct cil_tree_node *block_node = NULL; + struct cil_args_resolve *args = extra_args; + int rc = SEPOL_ERR; + + rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + block_node = NODE(block_datum); + if (block_node->flavor != CIL_BLOCK) { + cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc); + rc = SEPOL_ERR; + goto exit; + } + + cil_list_append(args->abstract_blocks, CIL_NODE, block_node); + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_in(struct cil_tree_node *current, void *extra_args) +{ + struct cil_in *in = current->data; + struct cil_args_resolve *args = extra_args; + struct cil_db *db = NULL; + struct cil_symtab_datum *block_datum = NULL; + struct cil_tree_node *block_node = NULL; + int rc = SEPOL_ERR; + + if (args != NULL) { + db = args->db; + } + + rc = cil_resolve_name(current, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + block_node = NODE(block_datum); + + if (block_node->flavor == CIL_OPTIONAL) { + if (block_datum->nodes && block_datum->nodes->head != block_datum->nodes->tail) { + cil_tree_log(current, CIL_ERR, "Multiple optional blocks referred to by in-statement"); + cil_tree_log(block_node, CIL_ERR, "First optional block"); + rc = SEPOL_ERR; + goto exit; + } + } + + rc = cil_copy_ast(db, current, block_node); + if (rc != SEPOL_OK) { + cil_tree_log(current, CIL_ERR, "Failed to copy in-statement"); + goto exit; + } + + cil_tree_children_destroy(current); + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_in_list(struct cil_list *in_list, void *extra_args) +{ + struct cil_list_item *curr = NULL; + struct cil_tree_node *node = NULL; + struct cil_tree_node *last_failed_node = NULL; + struct cil_in *in = NULL; + struct cil_symtab_datum *block_datum = NULL; + int resolved = 0; + int unresolved = 0; + int rc = SEPOL_ERR; + + do { + resolved = 0; + unresolved = 0; + + cil_list_for_each(curr, in_list) { + if (curr->flavor != CIL_NODE) { + continue; + } + + node = curr->data; + in = node->data; + + rc = cil_resolve_name(node, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); + if (rc != SEPOL_OK) { + unresolved++; + last_failed_node = node; + } else { + rc = cil_resolve_in(node, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + resolved++; + curr->data = NULL; + curr->flavor = CIL_NONE; + } + } + + if (unresolved > 0 && resolved == 0) { + cil_tree_log(last_failed_node, CIL_ERR, "Failed to resolve in-statement"); + rc = SEPOL_ERR; + goto exit; + } + + } while (unresolved > 0); + + rc = SEPOL_OK; + +exit: + return rc; +} + + +static int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor attr_flavor) +{ + int rc = SEPOL_ERR; + struct cil_bounds *bounds = current->data; + enum cil_sym_index index; + struct cil_symtab_datum *parent_datum = NULL; + struct cil_symtab_datum *child_datum = NULL; + + rc = cil_flavor_to_symtab_index(flavor, &index); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_resolve_name(current, bounds->parent_str, index, extra_args, &parent_datum); + if (rc != SEPOL_OK) { + goto exit; + } + if (FLAVOR(parent_datum) == attr_flavor) { + cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str); + rc = SEPOL_ERR; + goto exit; + } + + + rc = cil_resolve_name(current, bounds->child_str, index, extra_args, &child_datum); + if (rc != SEPOL_OK) { + goto exit; + } + if (FLAVOR(child_datum) == attr_flavor) { + cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str); + rc = SEPOL_ERR; + goto exit; + } + + switch (flavor) { + case CIL_USER: { + struct cil_user *user = (struct cil_user *)child_datum; + + if (user->bounds != NULL) { + cil_tree_log(NODE(user->bounds), CIL_ERR, "User %s already bound by parent", bounds->child_str); + rc = SEPOL_ERR; + goto exit; + } + + user->bounds = (struct cil_user *)parent_datum; + break; + } + case CIL_ROLE: { + struct cil_role *role = (struct cil_role *)child_datum; + + if (role->bounds != NULL) { + cil_tree_log(NODE(role->bounds), CIL_ERR, "Role %s already bound by parent", bounds->child_str); + rc = SEPOL_ERR; + goto exit; + } + + role->bounds = (struct cil_role *)parent_datum; + break; + } + case CIL_TYPE: { + struct cil_type *type = (struct cil_type *)child_datum; + + if (type->bounds != NULL) { + cil_tree_log(NODE(type->bounds), CIL_ERR, "Type %s already bound by parent", bounds->child_str); + rc = SEPOL_ERR; + goto exit; + } + + type->bounds = (struct cil_type *)parent_datum; + break; + } + default: + break; + } + + return SEPOL_OK; + +exit: + cil_tree_log(current, CIL_ERR, "Bad bounds statement"); + return rc; +} + +static int cil_resolve_default(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_default *def = current->data; + struct cil_list_item *curr; + struct cil_symtab_datum *datum; + + cil_list_init(&def->class_datums, def->flavor); + + cil_list_for_each(curr, def->class_strs) { + rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_append(def->class_datums, CIL_CLASS, datum); + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_defaultrange(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_defaultrange *def = current->data; + struct cil_list_item *curr; + struct cil_symtab_datum *datum; + + cil_list_init(&def->class_datums, CIL_DEFAULTRANGE); + + cil_list_for_each(curr, def->class_strs) { + rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_append(def->class_datums, CIL_CLASS, datum); + } + + return SEPOL_OK; + +exit: + return rc; +} + +static void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *terminating_node) +{ + struct cil_list *trace = NULL; + struct cil_list_item * item = NULL; + struct cil_tree_node *curr = NULL; + + cil_list_init(&trace, CIL_NODE); + + for (curr = call_node; curr != terminating_node; curr = curr->parent) { + if (curr->flavor == CIL_CALL) { + if (curr != call_node) { + cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)curr->data)->macro)); + } + cil_list_prepend(trace, CIL_NODE, curr); + } + } + + if (terminating_node->flavor == CIL_MACRO) { + cil_list_prepend(trace, CIL_NODE, terminating_node); + } else { + cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)terminating_node->data)->macro)); + } + + cil_list_for_each(item, trace) { + curr = item->data; + if (curr->flavor == CIL_MACRO) { + cil_tree_log(curr, CIL_ERR, "macro %s", DATUM(curr->data)->name); + } else { + cil_tree_log(curr, CIL_ERR, "call %s", ((struct cil_call *)curr->data)->macro_str); + } + } + + cil_list_destroy(&trace, CIL_FALSE); +} + +static int cil_check_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *macro_node) +{ + struct cil_tree_node *curr = NULL; + struct cil_call * call = NULL; + int rc = SEPOL_ERR; + + for (curr = call_node; curr != NULL; curr = curr->parent) { + if (curr->flavor == CIL_CALL) { + if (curr == call_node) { + continue; + } + + call = curr->data; + if (call->macro != macro_node->data) { + continue; + } + } else if (curr->flavor == CIL_MACRO) { + if (curr != macro_node) { + rc = SEPOL_OK; + goto exit; + } + } else { + continue; + } + + cil_log(CIL_ERR, "Recursive macro call found:\n"); + cil_print_recursive_call(call_node, curr); + + rc = SEPOL_ERR; + goto exit; + } + + rc = SEPOL_OK; +exit: + return rc; +} + +static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call *call, struct cil_macro *macro, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_list_item *item; + struct cil_args *arg = NULL; + struct cil_tree_node *arg_node = NULL; + int rc = SEPOL_ERR; + + if (macro->params == NULL) { + if (call->args_tree == NULL) { + return SEPOL_OK; + } else { + cil_tree_log(call_node, CIL_ERR, "Unexpected arguments"); + return SEPOL_ERR; + } + } + if (call->args_tree == NULL) { + cil_tree_log(call_node, CIL_ERR, "Missing arguments"); + return SEPOL_ERR; + } + + arg_node = call->args_tree->root->cl_head; + + cil_list_init(&call->args, CIL_LIST_ITEM); + + cil_list_for_each(item, macro->params) { + enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor; + + if (arg_node == NULL) { + cil_tree_log(call_node, CIL_ERR, "Missing arguments"); + rc = SEPOL_ERR; + goto exit; + } + if (item->flavor != CIL_PARAM) { + rc = SEPOL_ERR; + goto exit; + } + + cil_args_init(&arg); + + switch (flavor) { + case CIL_NAME: { + struct cil_name *name; + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + name = __cil_insert_name(args->db, arg_node->data, call_node); + if (name != NULL) { + arg->arg = (struct cil_symtab_datum *)name; + } else { + arg->arg_str = arg_node->data; + } + } + break; + case CIL_TYPE: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_ROLE: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_USER: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_SENS: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_CAT: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_BOOL: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_CATSET: { + if (arg_node->cl_head != NULL) { + struct cil_catset *catset = NULL; + struct cil_tree_node *cat_node = NULL; + cil_catset_init(&catset); + rc = cil_fill_cats(arg_node, &catset->cats); + if (rc != SEPOL_OK) { + cil_destroy_catset(catset); + cil_destroy_args(arg); + goto exit; + } + cil_tree_node_init(&cat_node); + cat_node->flavor = CIL_CATSET; + cat_node->data = catset; + cil_list_append(((struct cil_symtab_datum*)catset)->nodes, + CIL_LIST_ITEM, cat_node); + arg->arg = (struct cil_symtab_datum*)catset; + } else if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } else { + arg->arg_str = arg_node->data; + } + + break; + } + case CIL_LEVEL: { + if (arg_node->cl_head != NULL) { + struct cil_level *level = NULL; + struct cil_tree_node *lvl_node = NULL; + cil_level_init(&level); + + rc = cil_fill_level(arg_node->cl_head, level); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc); + cil_destroy_level(level); + cil_destroy_args(arg); + goto exit; + } + cil_tree_node_init(&lvl_node); + lvl_node->flavor = CIL_LEVEL; + lvl_node->data = level; + cil_list_append(((struct cil_symtab_datum*)level)->nodes, + CIL_LIST_ITEM, lvl_node); + arg->arg = (struct cil_symtab_datum*)level; + } else if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } else { + arg->arg_str = arg_node->data; + } + + break; + } + case CIL_LEVELRANGE: { + if (arg_node->cl_head != NULL) { + struct cil_levelrange *range = NULL; + struct cil_tree_node *range_node = NULL; + cil_levelrange_init(&range); + + rc = cil_fill_levelrange(arg_node->cl_head, range); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc); + cil_destroy_levelrange(range); + cil_destroy_args(arg); + goto exit; + } + cil_tree_node_init(&range_node); + range_node->flavor = CIL_LEVELRANGE; + range_node->data = range; + cil_list_append(((struct cil_symtab_datum*)range)->nodes, + CIL_LIST_ITEM, range_node); + arg->arg = (struct cil_symtab_datum*)range; + } else if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } else { + arg->arg_str = arg_node->data; + } + + break; + } + case CIL_IPADDR: { + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } else if (strchr(arg_node->data, '.') || strchr(arg_node->data, ':')) { + struct cil_ipaddr *ipaddr = NULL; + struct cil_tree_node *addr_node = NULL; + cil_ipaddr_init(&ipaddr); + rc = cil_fill_ipaddr(arg_node, ipaddr); + if (rc != SEPOL_OK) { + cil_tree_log(call_node, CIL_ERR, "Failed to create anonymous ip address"); + cil_destroy_ipaddr(ipaddr); + cil_destroy_args(arg); + goto exit; + } + cil_tree_node_init(&addr_node); + addr_node->flavor = CIL_IPADDR; + addr_node->data = ipaddr; + cil_list_append(DATUM(ipaddr)->nodes, CIL_LIST_ITEM, addr_node); + arg->arg = DATUM(ipaddr); + } else { + arg->arg_str = arg_node->data; + } + break; + } + case CIL_CLASS: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_MAP_CLASS: + if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->arg_str = arg_node->data; + break; + case CIL_CLASSPERMISSION: { + if (arg_node->cl_head != NULL) { + struct cil_classpermission *cp = NULL; + struct cil_tree_node *cp_node = NULL; + + cil_classpermission_init(&cp); + rc = cil_fill_classperms_list(arg_node, &cp->classperms); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to create anonymous classpermission\n"); + cil_destroy_classpermission(cp); + cil_destroy_args(arg); + goto exit; + } + cil_tree_node_init(&cp_node); + cp_node->flavor = CIL_CLASSPERMISSION; + cp_node->data = cp; + cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node); + arg->arg = (struct cil_symtab_datum*)cp; + } else if (arg_node->data == NULL) { + cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } else { + arg->arg_str = arg_node->data; + } + break; + } + default: + cil_log(CIL_ERR, "Unexpected flavor: %d\n", + (((struct cil_param*)item->data)->flavor)); + cil_destroy_args(arg); + rc = SEPOL_ERR; + goto exit; + } + arg->param_str = ((struct cil_param*)item->data)->str; + arg->flavor = flavor; + + cil_list_append(call->args, CIL_ARGS, arg); + + arg_node = arg_node->next; + } + + if (arg_node != NULL) { + cil_tree_log(call_node, CIL_ERR, "Unexpected arguments"); + rc = SEPOL_ERR; + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_call(struct cil_tree_node *current, void *extra_args) +{ + struct cil_call *call = current->data; + struct cil_args_resolve *args = extra_args; + struct cil_tree_node *macro_node = NULL; + struct cil_symtab_datum *macro_datum = NULL; + int rc = SEPOL_ERR; + + if (call->copied) { + return SEPOL_OK; + } + + rc = cil_resolve_name(current, call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum); + if (rc != SEPOL_OK) { + goto exit; + } + + macro_node = NODE(macro_datum); + + if (macro_node->flavor != CIL_MACRO) { + cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", call->macro_str); + rc = SEPOL_ERR; + goto exit; + } + call->macro = (struct cil_macro*)macro_datum; + + rc = cil_build_call_args(current, call, call->macro, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_check_recursive_call(current, macro_node); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_copy_ast(args->db, macro_node, current); + if (rc != SEPOL_OK) { + cil_tree_log(current, CIL_ERR, "Failed to copy macro %s to call", macro_datum->name); + goto exit; + } + + call->copied = 1; + + return SEPOL_OK; + +exit: + return rc; +} + +static int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args) +{ + struct cil_call *call = current->data; + int rc = SEPOL_ERR; + enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; + struct cil_list_item *item; + + if (call->args == NULL) { + rc = SEPOL_OK; + goto exit; + } + + cil_list_for_each(item, call->args) { + struct cil_args *arg = item->data; + if (arg->arg == NULL && arg->arg_str == NULL) { + cil_log(CIL_ERR, "Arguments not created correctly\n"); + rc = SEPOL_ERR; + goto exit; + } + + switch (arg->flavor) { + case CIL_NAME: + if (arg->arg != NULL) { + continue; /* No need to resolve */ + } else { + sym_index = CIL_SYM_NAMES; + } + break; + case CIL_LEVEL: + if (arg->arg_str == NULL && arg->arg != NULL) { + continue; // anonymous, no need to resolve + } else { + sym_index = CIL_SYM_LEVELS; + } + break; + case CIL_LEVELRANGE: + if (arg->arg_str == NULL && arg->arg != NULL) { + continue; // anonymous, no need to resolve + } else { + sym_index = CIL_SYM_LEVELRANGES; + } + break; + case CIL_CATSET: + if (arg->arg_str == NULL && arg->arg != NULL) { + continue; // anonymous, no need to resolve + } else { + sym_index = CIL_SYM_CATS; + } + break; + case CIL_IPADDR: + if (arg->arg_str == NULL && arg->arg != NULL) { + continue; // anonymous, no need to resolve + } else { + sym_index = CIL_SYM_IPADDRS; + } + break; + case CIL_CLASSPERMISSION: + if (arg->arg_str == NULL && arg->arg != NULL) { + continue; + } else { + sym_index = CIL_SYM_CLASSPERMSETS; + } + break; + case CIL_TYPE: + if (arg->arg_str == NULL && arg->arg != NULL) { + continue; // anonymous, no need to resolve + } else { + sym_index = CIL_SYM_TYPES; + } + break; + case CIL_ROLE: + sym_index = CIL_SYM_ROLES; + break; + case CIL_USER: + sym_index = CIL_SYM_USERS; + break; + case CIL_SENS: + sym_index = CIL_SYM_SENS; + break; + case CIL_CAT: + sym_index = CIL_SYM_CATS; + break; + case CIL_CLASS: + case CIL_MAP_CLASS: + sym_index = CIL_SYM_CLASSES; + break; + case CIL_BOOL: + sym_index = CIL_SYM_BOOLS; + break; + default: + rc = SEPOL_ERR; + goto exit; + } + + if (sym_index != CIL_SYM_UNKNOWN) { + struct cil_symtab_datum *datum; + struct cil_tree_node *n; + rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &datum); + if (rc != SEPOL_OK) { + cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str); + goto exit; + } + arg->arg = datum; + n = NODE(datum); + while (n && n->flavor != CIL_ROOT) { + if (n == current) { + symtab_t *s = datum->symtab; + /* Call arg should not resolve to declaration in the call + * Need to remove datum temporarily to resolve to a datum outside + * the call. + */ + cil_symtab_remove_datum(datum); + rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg)); + if (rc != SEPOL_OK) { + cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str); + goto exit; + } + rc = cil_symtab_insert(s, datum->name, datum, NULL); + if (rc != SEPOL_OK) { + cil_tree_log(current, CIL_ERR, "Failed to re-insert datum while resolving %s in call argument list", arg->arg_str); + goto exit; + } + break; + } + n = n->parent; + } + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) +{ + struct cil_list_item *item; + enum cil_sym_index param_index = CIL_SYM_UNKNOWN; + int rc = SEPOL_ERR; + + if (call == NULL || name == NULL) { + goto exit; + } + + if (call->args == NULL) { + goto exit; + } + + cil_list_for_each(item, call->args) { + struct cil_args * arg = item->data; + rc = cil_flavor_to_symtab_index(arg->flavor, ¶m_index); + if (param_index == sym_index) { + if (name == arg->param_str) { + *datum = arg->arg; + rc = *datum ? SEPOL_OK : SEPOL_ERR; + goto exit; + } + } + } + + return SEPOL_ERR; + +exit: + return rc; +} + +int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + struct cil_symtab_datum *res_datum = NULL; + enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; + struct cil_list *datum_sub_expr; + enum cil_flavor op = CIL_NONE; + + switch (str_expr->flavor) { + case CIL_BOOL: + sym_index = CIL_SYM_BOOLS; + break; + case CIL_TUNABLE: + sym_index = CIL_SYM_TUNABLES; + break; + case CIL_TYPE: + sym_index = CIL_SYM_TYPES; + break; + case CIL_ROLE: + sym_index = CIL_SYM_ROLES; + break; + case CIL_USER: + sym_index = CIL_SYM_USERS; + break; + case CIL_CAT: + sym_index = CIL_SYM_CATS; + break; + default: + break; + } + + cil_list_init(datum_expr, str_expr->flavor); + + cil_list_for_each(curr, str_expr) { + switch (curr->flavor) { + case CIL_STRING: + rc = cil_resolve_name(parent, curr->data, sym_index, extra_args, &res_datum); + if (rc != SEPOL_OK) { + goto exit; + } + if (sym_index == CIL_SYM_CATS && NODE(res_datum)->flavor == CIL_CATSET) { + struct cil_catset *catset = (struct cil_catset *)res_datum; + if (op == CIL_RANGE) { + cil_tree_log(parent, CIL_ERR, "Category set not allowed in category range"); + rc = SEPOL_ERR; + goto exit; + } + if (!res_datum->name) { + /* Anonymous category sets need to be resolved when encountered */ + if (!catset->cats->datum_expr) { + rc = cil_resolve_expr(expr_type, catset->cats->str_expr, &catset->cats->datum_expr, parent, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + cil_copy_list(catset->cats->datum_expr, &datum_sub_expr); + cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr); + } else { + cil_list_append(*datum_expr, CIL_DATUM, res_datum); + } + } else { + if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) { + cil_type_used(res_datum, CIL_ATTR_CONSTRAINT); + } + cil_list_append(*datum_expr, CIL_DATUM, res_datum); + } + break; + case CIL_LIST: { + rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr); + break; + } + default: + if (curr->flavor == CIL_OP) { + op = (enum cil_flavor)(uintptr_t)curr->data; + } + cil_list_append(*datum_expr, curr->flavor, curr->data); + break; + } + } + return SEPOL_OK; + +exit: + cil_list_destroy(datum_expr, CIL_FALSE); + return rc; +} + +int cil_resolve_boolif(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_booleanif *bif = (struct cil_booleanif*)current->data; + + rc = cil_resolve_expr(CIL_BOOLEANIF, bif->str_expr, &bif->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_evaluate_tunable_expr(struct cil_list_item *curr); + +static int __cil_evaluate_tunable_expr_helper(struct cil_list_item *curr) +{ + if (curr == NULL) { + return CIL_FALSE; + } else if (curr->flavor == CIL_DATUM) { + struct cil_tunable *tun = curr->data; + return tun->value; + } else if (curr->flavor == CIL_LIST) { + struct cil_list *l = curr->data; + return __cil_evaluate_tunable_expr(l->head); + } else { + return CIL_FALSE; + } +} + +static int __cil_evaluate_tunable_expr(struct cil_list_item *curr) +{ + /* Assumes expression is well-formed */ + + if (curr == NULL) { + return CIL_FALSE; + } else if (curr->flavor == CIL_OP) { + uint16_t v1, v2; + enum cil_flavor op_flavor = (enum cil_flavor)(uintptr_t)curr->data; + + v1 = __cil_evaluate_tunable_expr_helper(curr->next); + + if (op_flavor == CIL_NOT) return !v1; + + v2 = __cil_evaluate_tunable_expr_helper(curr->next->next); + + if (op_flavor == CIL_AND) return (v1 && v2); + else if (op_flavor == CIL_OR) return (v1 || v2); + else if (op_flavor == CIL_XOR) return (v1 ^ v2); + else if (op_flavor == CIL_EQ) return (v1 == v2); + else if (op_flavor == CIL_NEQ) return (v1 != v2); + else return CIL_FALSE; + } else { + uint16_t v; + for (;curr; curr = curr->next) { + v = __cil_evaluate_tunable_expr_helper(curr); + if (v) return v; + } + return CIL_FALSE; + } +} + +int cil_resolve_tunif(struct cil_tree_node *current, void *extra_args) +{ + struct cil_args_resolve *args = extra_args; + struct cil_db *db = NULL; + int rc = SEPOL_ERR; + struct cil_tunableif *tif = (struct cil_tunableif*)current->data; + uint16_t result = CIL_FALSE; + struct cil_tree_node *true_node = NULL; + struct cil_tree_node *false_node = NULL; + struct cil_condblock *cb = NULL; + + if (args != NULL) { + db = args->db; + } + + rc = cil_resolve_expr(CIL_TUNABLEIF, tif->str_expr, &tif->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + result = __cil_evaluate_tunable_expr(tif->datum_expr->head); + + if (current->cl_head != NULL && current->cl_head->flavor == CIL_CONDBLOCK) { + cb = current->cl_head->data; + if (cb->flavor == CIL_CONDTRUE) { + true_node = current->cl_head; + } else if (cb->flavor == CIL_CONDFALSE) { + false_node = current->cl_head; + } + } + + if (current->cl_head != NULL && current->cl_head->next != NULL && current->cl_head->next->flavor == CIL_CONDBLOCK) { + cb = current->cl_head->next->data; + if (cb->flavor == CIL_CONDTRUE) { + true_node = current->cl_head->next; + } else if (cb->flavor == CIL_CONDFALSE) { + false_node = current->cl_head->next; + } + } + + if (result == CIL_TRUE) { + if (true_node != NULL) { + rc = cil_copy_ast(db, true_node, current->parent); + if (rc != SEPOL_OK) { + goto exit; + } + } + } else { + if (false_node != NULL) { + rc = cil_copy_ast(db, false_node, current->parent); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + cil_tree_children_destroy(current); + current->cl_head = NULL; + current->cl_tail = NULL; + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_userattributeset *attrusers = current->data; + struct cil_symtab_datum *attr_datum = NULL; + struct cil_tree_node *attr_node = NULL; + struct cil_userattribute *attr = NULL; + + rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, extra_args, &attr_datum); + if (rc != SEPOL_OK) { + goto exit; + } + attr_node = NODE(attr_datum); + + if (attr_node->flavor != CIL_USERATTRIBUTE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Attribute user not an attribute\n"); + goto exit; + } + attr = (struct cil_userattribute*)attr_datum; + + rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + if (attr->expr_list == NULL) { + cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE); + } + + cil_list_append(attr->expr_list, CIL_LIST, attrusers->datum_expr); + + return SEPOL_OK; + +exit: + return rc; +} + +/* + * Degenerate inheritance leads to exponential growth of the policy + * It can take many forms, but here is one example. + * ... + * (blockinherit ba) + * (block b0 + * (block b1 + * (block b2 + * (block b3 + * ... + * ) + * (blockinherit b3) + * ) + * (blockinherit b2) + * ) + * (blockinherit b1) + * ) + * (blockinherit b0) + * ... + * This leads to 2^4 copies of the content of block b3, 2^3 copies of the + * contents of block b2, etc. + */ +static unsigned cil_count_actual(struct cil_tree_node *node) +{ + unsigned count = 0; + + if (node->flavor == CIL_BLOCKINHERIT) { + count += 1; + } + + for (node = node->cl_head; node; node = node->next) { + count += cil_count_actual(node); + } + + return count; +} + +static int cil_check_inheritances(struct cil_tree_node *node, unsigned max, unsigned *count, struct cil_stack *stack, unsigned *loop) +{ + int rc; + + if (node->flavor == CIL_BLOCKINHERIT) { + struct cil_blockinherit *bi = node->data; + *count += 1; + if (*count > max) { + cil_tree_log(node, CIL_ERR, "Degenerate inheritance detected"); + return SEPOL_ERR; + } + if (bi->block) { + struct cil_tree_node *block_node = NODE(bi->block); + struct cil_stack_item *item; + int i = 0; + cil_stack_for_each(stack, i, item) { + if (block_node == (struct cil_tree_node *)item->data) { + *loop = CIL_TRUE; + cil_tree_log(block_node, CIL_ERR, "Block inheritance loop found"); + cil_tree_log(node, CIL_ERR, " blockinherit"); + return SEPOL_ERR; + } + } + cil_stack_push(stack, CIL_BLOCK, block_node); + rc = cil_check_inheritances(block_node, max, count, stack, loop); + cil_stack_pop(stack); + if (rc != SEPOL_OK) { + if (*loop == CIL_TRUE) { + cil_tree_log(node, CIL_ERR, " blockinherit"); + } + return SEPOL_ERR; + } + } + } + + for (node = node->cl_head; node; node = node->next) { + rc = cil_check_inheritances(node, max, count, stack, loop); + if (rc != SEPOL_OK) { + return SEPOL_ERR; + } + } + + return SEPOL_OK; +} + +static int cil_check_for_bad_inheritance(struct cil_tree_node *node) +{ + unsigned num_actual, max; + unsigned num_potential = 0; + unsigned loop = CIL_FALSE; + struct cil_stack *stack; + int rc; + + num_actual = cil_count_actual(node); + + max = num_actual * CIL_DEGENERATE_INHERITANCE_GROWTH; + if (max < CIL_DEGENERATE_INHERITANCE_MINIMUM) { + max = CIL_DEGENERATE_INHERITANCE_MINIMUM; + } + + cil_stack_init(&stack); + rc = cil_check_inheritances(node, max, &num_potential, stack, &loop); + cil_stack_destroy(&stack); + + return rc; +} + +static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) +{ + int rc = SEPOL_OK; + struct cil_args_resolve *args = extra_args; + enum cil_pass pass = 0; + + if (node == NULL || args == NULL) { + goto exit; + } + + pass = args->pass; + switch (pass) { + case CIL_PASS_TIF: + if (node->flavor == CIL_TUNABLEIF) { + rc = cil_resolve_tunif(node, args); + } + break; + case CIL_PASS_IN_BEFORE: + if (node->flavor == CIL_IN) { + // due to ordering issues, in statements are just gathered here and + // resolved together in cil_resolve_in_list once all are found + struct cil_in *in = node->data; + if (in->is_after == CIL_FALSE) { + cil_list_prepend(args->in_list_before, CIL_NODE, node); + } + } + break; + case CIL_PASS_BLKIN_LINK: + if (node->flavor == CIL_BLOCKINHERIT) { + rc = cil_resolve_blockinherit_link(node, args); + } + break; + case CIL_PASS_BLKIN_COPY: + if (node->flavor == CIL_BLOCK) { + rc = cil_resolve_blockinherit_copy(node, args); + } + break; + case CIL_PASS_BLKABS: + if (node->flavor == CIL_BLOCKABSTRACT) { + rc = cil_resolve_blockabstract(node, args); + } + break; + case CIL_PASS_IN_AFTER: + if (node->flavor == CIL_IN) { + // due to ordering issues, in statements are just gathered here and + // resolved together in cil_resolve_in_list once all are found + struct cil_in *in = node->data; + if (in->is_after == CIL_TRUE) { + cil_list_prepend(args->in_list_after, CIL_NODE, node); + } + } + break; + case CIL_PASS_CALL1: + if (node->flavor == CIL_CALL && args->macro == NULL) { + rc = cil_resolve_call(node, args); + } + break; + case CIL_PASS_CALL2: + if (node->flavor == CIL_CALL && args->macro == NULL) { + rc = cil_resolve_call_args(node, args); + } + break; + case CIL_PASS_ALIAS1: + switch (node->flavor) { + case CIL_TYPEALIASACTUAL: + rc = cil_resolve_aliasactual(node, args, CIL_TYPE, CIL_TYPEALIAS); + break; + case CIL_SENSALIASACTUAL: + rc = cil_resolve_aliasactual(node, args, CIL_SENS, CIL_SENSALIAS); + break; + case CIL_CATALIASACTUAL: + rc = cil_resolve_aliasactual(node, args, CIL_CAT, CIL_CATALIAS); + break; + default: + break; + } + break; + case CIL_PASS_ALIAS2: + switch (node->flavor) { + case CIL_TYPEALIAS: + rc = cil_resolve_alias_to_actual(node, CIL_TYPE); + break; + case CIL_SENSALIAS: + rc = cil_resolve_alias_to_actual(node, CIL_SENS); + break; + case CIL_CATALIAS: + rc = cil_resolve_alias_to_actual(node, CIL_CAT); + break; + default: + break; + } + break; + case CIL_PASS_MISC1: + switch (node->flavor) { + case CIL_SIDORDER: + rc = cil_resolve_sidorder(node, args); + break; + case CIL_CLASSORDER: + rc = cil_resolve_classorder(node, args); + break; + case CIL_CATORDER: + rc = cil_resolve_catorder(node, args); + break; + case CIL_SENSITIVITYORDER: + rc = cil_resolve_sensitivityorder(node, args); + break; + case CIL_BOOLEANIF: + rc = cil_resolve_boolif(node, args); + break; + default: + break; + } + break; + case CIL_PASS_MLS: + switch (node->flavor) { + case CIL_CATSET: + rc = cil_resolve_catset(node, (struct cil_catset*)node->data, args); + break; + default: + break; + } + break; + case CIL_PASS_MISC2: + switch (node->flavor) { + case CIL_SENSCAT: + rc = cil_resolve_senscat(node, args); + break; + case CIL_CLASSCOMMON: + rc = cil_resolve_classcommon(node, args); + break; + default: + break; + } + break; + case CIL_PASS_MISC3: + switch (node->flavor) { + case CIL_TYPEATTRIBUTESET: + rc = cil_resolve_typeattributeset(node, args); + break; + case CIL_EXPANDTYPEATTRIBUTE: + rc = cil_resolve_expandtypeattribute(node, args); + break; + case CIL_TYPEBOUNDS: + rc = cil_resolve_bounds(node, args, CIL_TYPE, CIL_TYPEATTRIBUTE); + break; + case CIL_TYPEPERMISSIVE: + rc = cil_resolve_typepermissive(node, args); + break; + case CIL_NAMETYPETRANSITION: + rc = cil_resolve_nametypetransition(node, args); + break; + case CIL_RANGETRANSITION: + rc = cil_resolve_rangetransition(node, args); + break; + case CIL_CLASSPERMISSIONSET: + rc = cil_resolve_classpermissionset(node, (struct cil_classpermissionset*)node->data, args); + break; + case CIL_CLASSMAPPING: + rc = cil_resolve_classmapping(node, args); + break; + case CIL_AVRULE: + case CIL_AVRULEX: + rc = cil_resolve_avrule(node, args); + break; + case CIL_PERMISSIONX: + rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, args); + break; + case CIL_TYPE_RULE: + rc = cil_resolve_type_rule(node, args); + break; + case CIL_USERROLE: + rc = cil_resolve_userrole(node, args); + break; + case CIL_USERLEVEL: + rc = cil_resolve_userlevel(node, args); + break; + case CIL_USERRANGE: + rc = cil_resolve_userrange(node, args); + break; + case CIL_USERBOUNDS: + rc = cil_resolve_bounds(node, args, CIL_USER, CIL_USERATTRIBUTE); + break; + case CIL_USERPREFIX: + rc = cil_resolve_userprefix(node, args); + break; + case CIL_SELINUXUSER: + case CIL_SELINUXUSERDEFAULT: + rc = cil_resolve_selinuxuser(node, args); + break; + case CIL_ROLEATTRIBUTESET: + rc = cil_resolve_roleattributeset(node, args); + break; + case CIL_ROLETYPE: + rc = cil_resolve_roletype(node, args); + break; + case CIL_ROLETRANSITION: + rc = cil_resolve_roletransition(node, args); + break; + case CIL_ROLEALLOW: + rc = cil_resolve_roleallow(node, args); + break; + case CIL_ROLEBOUNDS: + rc = cil_resolve_bounds(node, args, CIL_ROLE, CIL_ROLEATTRIBUTE); + break; + case CIL_LEVEL: + rc = cil_resolve_level(node, (struct cil_level*)node->data, args); + break; + case CIL_LEVELRANGE: + rc = cil_resolve_levelrange(node, (struct cil_levelrange*)node->data, args); + break; + case CIL_CONSTRAIN: + rc = cil_resolve_constrain(node, args); + break; + case CIL_MLSCONSTRAIN: + rc = cil_resolve_constrain(node, args); + break; + case CIL_VALIDATETRANS: + case CIL_MLSVALIDATETRANS: + rc = cil_resolve_validatetrans(node, args); + break; + case CIL_CONTEXT: + rc = cil_resolve_context(node, (struct cil_context*)node->data, args); + break; + case CIL_FILECON: + rc = cil_resolve_filecon(node, args); + break; + case CIL_IBPKEYCON: + rc = cil_resolve_ibpkeycon(node, args); + break; + case CIL_PORTCON: + rc = cil_resolve_portcon(node, args); + break; + case CIL_NODECON: + rc = cil_resolve_nodecon(node, args); + break; + case CIL_GENFSCON: + rc = cil_resolve_genfscon(node, args); + break; + case CIL_NETIFCON: + rc = cil_resolve_netifcon(node, args); + break; + case CIL_IBENDPORTCON: + rc = cil_resolve_ibendportcon(node, args); + break; + case CIL_PIRQCON: + rc = cil_resolve_pirqcon(node, args); + break; + case CIL_IOMEMCON: + rc = cil_resolve_iomemcon(node, args); + break; + case CIL_IOPORTCON: + rc = cil_resolve_ioportcon(node, args); + break; + case CIL_PCIDEVICECON: + rc = cil_resolve_pcidevicecon(node, args); + break; + case CIL_DEVICETREECON: + rc = cil_resolve_devicetreecon(node, args); + break; + case CIL_FSUSE: + rc = cil_resolve_fsuse(node, args); + break; + case CIL_SIDCONTEXT: + rc = cil_resolve_sidcontext(node, args); + break; + case CIL_DEFAULTUSER: + case CIL_DEFAULTROLE: + case CIL_DEFAULTTYPE: + rc = cil_resolve_default(node, args); + break; + case CIL_DEFAULTRANGE: + rc = cil_resolve_defaultrange(node, args); + break; + case CIL_USERATTRIBUTESET: + rc = cil_resolve_userattributeset(node, args); + break; + default: + break; + } + break; + default: + break; + } + + return rc; + +exit: + return rc; +} + +static int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_OK; + struct cil_args_resolve *args = extra_args; + enum cil_pass pass = args->pass; + struct cil_tree_node *block = args->block; + struct cil_tree_node *macro = args->macro; + struct cil_tree_node *optional = args->optional; + struct cil_tree_node *boolif = args->boolif; + + if (node == NULL) { + goto exit; + } + + if (block != NULL) { + if (node->flavor == CIL_CAT || + node->flavor == CIL_SENS) { + cil_tree_log(node, CIL_ERR, "%s is not allowed in block", cil_node_to_string(node)); + rc = SEPOL_ERR; + goto exit; + } + } + + if (macro != NULL) { + if (node->flavor == CIL_TUNABLE || + node->flavor == CIL_IN || + node->flavor == CIL_BLOCK || + node->flavor == CIL_BLOCKINHERIT || + node->flavor == CIL_BLOCKABSTRACT || + node->flavor == CIL_MACRO) { + cil_tree_log(node, CIL_ERR, "%s is not allowed in macro", cil_node_to_string(node)); + rc = SEPOL_ERR; + goto exit; + } + } + + if (optional != NULL) { + if (node->flavor == CIL_TUNABLE || + node->flavor == CIL_IN || + node->flavor == CIL_BLOCK || + node->flavor == CIL_BLOCKABSTRACT || + node->flavor == CIL_MACRO) { + cil_tree_log(node, CIL_ERR, "%s is not allowed in optional", cil_node_to_string(node)); + rc = SEPOL_ERR; + goto exit; + } + } + + if (boolif != NULL) { + if (node->flavor != CIL_TUNABLEIF && + node->flavor != CIL_CALL && + node->flavor != CIL_CONDBLOCK && + node->flavor != CIL_AVRULE && + node->flavor != CIL_TYPE_RULE && + node->flavor != CIL_NAMETYPETRANSITION) { + rc = SEPOL_ERR; + } else if (node->flavor == CIL_AVRULE) { + struct cil_avrule *rule = node->data; + if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) { + rc = SEPOL_ERR; + } + } + if (rc == SEPOL_ERR) { + if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { + cil_tree_log(node, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", cil_node_to_string(node)); + } else { + cil_tree_log(node, CIL_ERR, "%s is not allowed in booleanif", cil_node_to_string(node)); + } + goto exit; + } + } + + if (node->flavor == CIL_MACRO) { + if (pass > CIL_PASS_IN_AFTER) { + *finished = CIL_TREE_SKIP_HEAD; + rc = SEPOL_OK; + goto exit; + } + } + + if (node->flavor == CIL_BLOCK && ((((struct cil_block*)node->data)->is_abstract == CIL_TRUE) && (pass > CIL_PASS_BLKABS))) { + *finished = CIL_TREE_SKIP_HEAD; + rc = SEPOL_OK; + goto exit; + } + + rc = __cil_resolve_ast_node(node, extra_args); + if (rc == SEPOL_ENOENT) { + if (optional == NULL) { + cil_tree_log(node, CIL_ERR, "Failed to resolve %s statement", cil_node_to_string(node)); + } else { + if (!args->disabled_optional) { + args->disabled_optional = optional; + } + cil_tree_log(node, CIL_INFO, "Failed to resolve %s statement", cil_node_to_string(node)); + cil_tree_log(optional, CIL_INFO, "Disabling optional '%s'", DATUM(optional->data)->name); + rc = SEPOL_OK; + } + goto exit; + } + + return rc; + +exit: + return rc; +} + +static int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_args_resolve *args = extra_args; + struct cil_tree_node *parent = NULL; + + if (current == NULL || extra_args == NULL) { + goto exit; + } + + parent = current->parent; + + if (parent->flavor == CIL_BLOCK) { + args->block = parent; + } else if (parent->flavor == CIL_MACRO) { + args->macro = parent; + } else if (parent->flavor == CIL_OPTIONAL) { + args->optional = parent; + } else if (parent->flavor == CIL_BOOLEANIF) { + args->boolif = parent; + } + + return SEPOL_OK; + +exit: + return rc; + +} + +static int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_args_resolve *args = extra_args; + struct cil_tree_node *parent = NULL; + + if (current == NULL || extra_args == NULL) { + goto exit; + } + + parent = current->parent; + + if (parent->flavor == CIL_BLOCK) { + struct cil_tree_node *n = parent->parent; + args->block = NULL; + while (n && n->flavor != CIL_ROOT) { + if (n->flavor == CIL_BLOCK) { + args->block = n; + break; + } + n = n->parent; + } + } else if (parent->flavor == CIL_MACRO) { + args->macro = NULL; + } else if (parent->flavor == CIL_OPTIONAL) { + struct cil_tree_node *n = parent->parent; + if (args->disabled_optional == parent) { + *(args->changed) = CIL_TRUE; + cil_list_append(args->to_destroy, CIL_NODE, parent); + args->disabled_optional = NULL; + } + args->optional = NULL; + while (n && n->flavor != CIL_ROOT) { + if (n->flavor == CIL_OPTIONAL) { + args->optional = n; + break; + } + n = n->parent; + } + } else if (parent->flavor == CIL_BOOLEANIF) { + args->boolif = NULL; + } + + return SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) +{ + int rc = SEPOL_ERR; + struct cil_args_resolve extra_args; + enum cil_pass pass = CIL_PASS_TIF; + uint32_t changed = 0; + + if (db == NULL || current == NULL) { + return rc; + } + + extra_args.db = db; + extra_args.pass = pass; + extra_args.changed = &changed; + extra_args.block = NULL; + extra_args.macro = NULL; + extra_args.optional = NULL; + extra_args.disabled_optional = NULL; + extra_args.boolif= NULL; + extra_args.sidorder_lists = NULL; + extra_args.classorder_lists = NULL; + extra_args.unordered_classorder_lists = NULL; + extra_args.catorder_lists = NULL; + extra_args.sensitivityorder_lists = NULL; + extra_args.in_list_before = NULL; + extra_args.in_list_after = NULL; + extra_args.abstract_blocks = NULL; + + cil_list_init(&extra_args.to_destroy, CIL_NODE); + cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM); + cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM); + cil_list_init(&extra_args.unordered_classorder_lists, CIL_LIST_ITEM); + cil_list_init(&extra_args.catorder_lists, CIL_LIST_ITEM); + cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM); + cil_list_init(&extra_args.in_list_before, CIL_IN); + cil_list_init(&extra_args.in_list_after, CIL_IN); + cil_list_init(&extra_args.abstract_blocks, CIL_NODE); + + for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) { + extra_args.pass = pass; + rc = cil_tree_walk(current, __cil_resolve_ast_node_helper, __cil_resolve_ast_first_child_helper, __cil_resolve_ast_last_child_helper, &extra_args); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Pass %i of resolution failed\n", pass); + goto exit; + } + + if (pass == CIL_PASS_IN_BEFORE) { + rc = cil_resolve_in_list(extra_args.in_list_before, &extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_destroy(&extra_args.in_list_before, CIL_FALSE); + } else if (pass == CIL_PASS_IN_AFTER) { + rc = cil_resolve_in_list(extra_args.in_list_after, &extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_destroy(&extra_args.in_list_after, CIL_FALSE); + } + + if (pass == CIL_PASS_BLKABS) { + struct cil_list_item *item; + cil_list_for_each(item, extra_args.abstract_blocks) { + cil_mark_subtree_abstract(item->data); + } + } + + if (pass == CIL_PASS_BLKIN_LINK) { + rc = cil_check_for_bad_inheritance(current); + if (rc != SEPOL_OK) { + rc = SEPOL_ERR; + goto exit; + } + } + + if (pass == CIL_PASS_MISC1) { + db->sidorder = __cil_ordered_lists_merge_all(&extra_args.sidorder_lists, NULL); + if (db->sidorder == NULL) { + rc = SEPOL_ERR; + goto exit; + } + db->classorder = __cil_ordered_lists_merge_all(&extra_args.classorder_lists, &extra_args.unordered_classorder_lists); + if (db->classorder == NULL) { + rc = SEPOL_ERR; + goto exit; + } + db->catorder = __cil_ordered_lists_merge_all(&extra_args.catorder_lists, NULL); + if (db->catorder == NULL) { + rc = SEPOL_ERR; + goto exit; + } + cil_set_cat_values(db->catorder, db); + db->sensitivityorder = __cil_ordered_lists_merge_all(&extra_args.sensitivityorder_lists, NULL); + if (db->sensitivityorder == NULL) { + rc = SEPOL_ERR; + goto exit; + } + + rc = __cil_verify_ordered(current, CIL_SID); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_verify_ordered(current, CIL_CLASS); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_verify_ordered(current, CIL_CAT); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_verify_ordered(current, CIL_SENS); + if (rc != SEPOL_OK) { + goto exit; + } + } + + if (changed) { + struct cil_list_item *item; + if (pass > CIL_PASS_CALL1) { + int has_decls = CIL_FALSE; + + cil_list_for_each(item, extra_args.to_destroy) { + has_decls = cil_tree_subtree_has_decl(item->data); + if (has_decls) { + break; + } + } + + if (has_decls) { + /* Need to re-resolve because an optional was disabled that + * contained one or more declarations. + * Everything that needs to be reset comes after the + * CIL_PASS_CALL2 pass. We set pass to CIL_PASS_CALL1 because + * the pass++ will increment it to CIL_PASS_CALL2 + */ + cil_log(CIL_INFO, "Resetting declarations\n"); + + if (pass >= CIL_PASS_MISC1) { + __cil_ordered_lists_reset(&extra_args.sidorder_lists); + __cil_ordered_lists_reset(&extra_args.classorder_lists); + __cil_ordered_lists_reset(&extra_args.unordered_classorder_lists); + __cil_ordered_lists_reset(&extra_args.catorder_lists); + __cil_ordered_lists_reset(&extra_args.sensitivityorder_lists); + cil_list_destroy(&db->sidorder, CIL_FALSE); + cil_list_destroy(&db->classorder, CIL_FALSE); + cil_list_destroy(&db->catorder, CIL_FALSE); + cil_list_destroy(&db->sensitivityorder, CIL_FALSE); + } + + pass = CIL_PASS_CALL1; + + rc = cil_reset_ast(current); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to reset declarations\n"); + goto exit; + } + } + } + cil_list_for_each(item, extra_args.to_destroy) { + cil_tree_children_destroy(item->data); + } + cil_list_destroy(&extra_args.to_destroy, CIL_FALSE); + cil_list_init(&extra_args.to_destroy, CIL_NODE); + changed = 0; + } + } + + rc = __cil_verify_initsids(db->sidorder); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = SEPOL_OK; +exit: + __cil_ordered_lists_destroy(&extra_args.sidorder_lists); + __cil_ordered_lists_destroy(&extra_args.classorder_lists); + __cil_ordered_lists_destroy(&extra_args.catorder_lists); + __cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists); + __cil_ordered_lists_destroy(&extra_args.unordered_classorder_lists); + cil_list_destroy(&extra_args.to_destroy, CIL_FALSE); + cil_list_destroy(&extra_args.in_list_before, CIL_FALSE); + cil_list_destroy(&extra_args.in_list_after, CIL_FALSE); + cil_list_destroy(&extra_args.abstract_blocks, CIL_FALSE); + + return rc; +} + +static int __cil_resolve_name_with_root(struct cil_db *db, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) +{ + symtab_t *symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index]; + + return cil_symtab_get_datum(symtab, name, datum); +} + +static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) +{ + int rc = SEPOL_ERR; + symtab_t *symtab = NULL; + + while (node != NULL && rc != SEPOL_OK) { + switch (node->flavor) { + case CIL_ROOT: + goto exit; + break; + case CIL_BLOCK: { + struct cil_block *block = node->data; + if (!block->is_abstract) { + symtab = &block->symtab[sym_index]; + rc = cil_symtab_get_datum(symtab, name, datum); + } + } + break; + case CIL_BLOCKINHERIT: { + struct cil_blockinherit *inherit = node->data; + rc = __cil_resolve_name_with_parents(node->parent, name, sym_index, datum); + if (rc != SEPOL_OK) { + /* Continue search in original block's parent */ + rc = __cil_resolve_name_with_parents(NODE(inherit->block)->parent, name, sym_index, datum); + goto exit; + } + } + break; + case CIL_MACRO: { + struct cil_macro *macro = node->data; + symtab = ¯o->symtab[sym_index]; + rc = cil_symtab_get_datum(symtab, name, datum); + } + break; + case CIL_CALL: { + struct cil_call *call = node->data; + struct cil_macro *macro = call->macro; + symtab = ¯o->symtab[sym_index]; + rc = cil_symtab_get_datum(symtab, name, datum); + if (rc == SEPOL_OK) { + /* If the name was declared in the macro, just look on the call side */ + rc = SEPOL_ERR; + } else { + rc = cil_resolve_name_call_args(call, name, sym_index, datum); + if (rc != SEPOL_OK) { + /* Continue search in macro's parent */ + rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum); + } + } + } + break; + case CIL_IN: + /* In block symtabs only exist before resolving the AST */ + case CIL_CONDBLOCK: + /* Cond block symtabs only exist before resolving the AST */ + default: + break; + } + + node = node->parent; + } + +exit: + return rc; +} + +static int __cil_resolve_name_helper(struct cil_db *db, struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) +{ + int rc = SEPOL_ERR; + + rc = __cil_resolve_name_with_parents(node, name, sym_index, datum); + if (rc != SEPOL_OK) { + rc = __cil_resolve_name_with_root(db, name, sym_index, datum); + } + return rc; +} + +int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *node = NULL; + + rc = cil_resolve_name_keep_aliases(ast_node, name, sym_index, extra_args, datum); + if (rc != SEPOL_OK) { + goto exit; + } + + /* If this datum is an alias, then return the actual node + * This depends on aliases already being processed + */ + node = NODE(*datum); + if (node->flavor == CIL_TYPEALIAS || node->flavor == CIL_SENSALIAS + || node->flavor == CIL_CATALIAS) { + struct cil_alias *alias = (struct cil_alias *)(*datum); + if (alias->actual) { + *datum = alias->actual; + } + } + + rc = SEPOL_OK; + +exit: + return rc; +} + +int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum) +{ + int rc = SEPOL_ERR; + struct cil_args_resolve *args = extra_args; + struct cil_db *db = args->db; + struct cil_tree_node *node = NULL; + + if (name == NULL) { + cil_log(CIL_ERR, "Invalid call to cil_resolve_name\n"); + goto exit; + } + + *datum = NULL; + + if (db->qualified_names || strchr(name,'.') == NULL) { + /* Using qualified names or No '.' in name */ + rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum); + if (rc != SEPOL_OK) { + goto exit; + } + } else { + char *sp = NULL; + char *name_dup = cil_strdup(name); + char *current = strtok_r(name_dup, ".", &sp); + char *next = strtok_r(NULL, ".", &sp); + symtab_t *symtab = NULL; + + if (current == NULL) { + /* Only dots */ + cil_tree_log(ast_node, CIL_ERR, "Invalid name %s", name); + free(name_dup); + goto exit; + } + + node = ast_node; + if (*name == '.') { + /* Leading '.' */ + symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_BLOCKS]; + } else { + rc = __cil_resolve_name_helper(db, node->parent, current, CIL_SYM_BLOCKS, datum); + if (rc != SEPOL_OK) { + free(name_dup); + goto exit; + } + symtab = (*datum)->symtab; + } + /* Keep looking up blocks by name until only last part of name remains */ + while (next != NULL) { + rc = cil_symtab_get_datum(symtab, current, datum); + if (rc != SEPOL_OK) { + free(name_dup); + goto exit; + } + node = NODE(*datum); + if (node->flavor == CIL_BLOCK) { + symtab = &((struct cil_block*)node->data)->symtab[CIL_SYM_BLOCKS]; + } else { + if (ast_node->flavor != CIL_IN) { + cil_log(CIL_WARN, "Can only use %s name for name resolution in \"in\" blocks\n", cil_node_to_string(node)); + free(name_dup); + rc = SEPOL_ERR; + goto exit; + } + if (node->flavor == CIL_MACRO) { + struct cil_macro *macro = node->data; + symtab = ¯o->symtab[sym_index]; + } + } + current = next; + next = strtok_r(NULL, ".", &sp); + } + symtab = &(symtab[sym_index]); + rc = cil_symtab_get_datum(symtab, current, datum); + free(name_dup); + if (rc != SEPOL_OK) { + goto exit; + } + } + + rc = SEPOL_OK; + +exit: + if (rc != SEPOL_OK) { + *datum = NULL; + } + + return rc; +} diff --git a/kernel/libsepol/cil/src/cil_resolve_ast.h b/kernel/libsepol/cil/src/cil_resolve_ast.h new file mode 100644 index 00000000..1d971fd6 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_resolve_ast.h @@ -0,0 +1,104 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_RESOLVE_AST_H_ +#define CIL_RESOLVE_AST_H_ + +#include + +#include "cil_internal.h" +#include "cil_tree.h" + +int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args); +int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, void *extra_args); +int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, void *extra_args); +int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, void *extra_args); +int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args); +int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args); +int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args); +int cil_resolve_typealias(struct cil_tree_node *current, void *extra_args); +int cil_resolve_typebounds(struct cil_tree_node *current, void *extra_args); +int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args); +int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_args); +int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args); +int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args); +int cil_resolve_userrole(struct cil_tree_node *current, void *extra_args); +int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args); +int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args); +int cil_resolve_userbounds(struct cil_tree_node *current, void *extra_args); +int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args); +int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args); +int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args); +int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args); +int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args); +int cil_resolve_roleallow(struct cil_tree_node *current, void *extra_args); +int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args); +int cil_resolve_rolebounds(struct cil_tree_node *current, void *extra_args); +int cil_resolve_sensalias(struct cil_tree_node *current, void *extra_args); +int cil_resolve_catalias(struct cil_tree_node *current, void *extra_args); +int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args); +int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args); +int cil_resolve_cat_list(struct cil_tree_node *current, struct cil_list *cat_list, struct cil_list *res_cat_list, void *extra_args); +int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args); +int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args); +int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, void *extra_args); +int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *levelrange, void *extra_args); +int cil_resolve_constrain(struct cil_tree_node *current, void *extra_args); +int cil_resolve_validatetrans(struct cil_tree_node *current, void *extra_args); +int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, void *extra_args); +int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_ibpkeycon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_genfscon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_netifcon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_pirqcon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_iomemcon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_ioportcon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_pcidevicecon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args); +int cil_resolve_sidcontext(struct cil_tree_node *current, void *extra_args); +int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args); +int cil_resolve_blockinherit(struct cil_tree_node *current, void *extra_args); +int cil_resolve_in(struct cil_tree_node *current, void *extra_args); +int cil_resolve_call1(struct cil_tree_node *current, void *extra_args); +int cil_resolve_call2(struct cil_tree_node *, void *extra_args); +int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum); +int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, void *extra_args); +int cil_resolve_boolif(struct cil_tree_node *current, void *extra_args); +int cil_evaluate_expr(struct cil_list *datum_expr, uint16_t *result); +int cil_resolve_tunif(struct cil_tree_node *current, void *extra_args); + +int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current); +int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum); +int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum); + +#endif /* CIL_RESOLVE_AST_H_ */ diff --git a/kernel/libsepol/cil/src/cil_stack.c b/kernel/libsepol/cil/src/cil_stack.c new file mode 100644 index 00000000..70a77bc1 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_stack.c @@ -0,0 +1,116 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "cil_internal.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_stack.h" + + +#define CIL_STACK_INIT_SIZE 16 + +void cil_stack_init(struct cil_stack **stack) +{ + struct cil_stack *new_stack = cil_malloc(sizeof(*new_stack)); + new_stack->stack = cil_malloc(sizeof(*(new_stack->stack)) * CIL_STACK_INIT_SIZE); + new_stack->size = CIL_STACK_INIT_SIZE; + new_stack->pos = -1; + *stack = new_stack; +} + +void cil_stack_destroy(struct cil_stack **stack) +{ + if (stack == NULL || *stack == NULL) { + return; + } + + free((*stack)->stack); + free(*stack); + *stack = NULL; +} + +void cil_stack_empty(struct cil_stack *stack) +{ + stack->pos = -1; +} + +int cil_stack_is_empty(struct cil_stack *stack) +{ + return (stack->pos == -1); +} + +int cil_stack_number_of_items(struct cil_stack *stack) +{ + return stack->pos + 1; +} + +void cil_stack_push(struct cil_stack *stack, enum cil_flavor flavor, void *data) +{ + stack->pos++; + + if (stack->pos == stack->size) { + stack->size *= 2; + stack->stack = cil_realloc(stack->stack, sizeof(*stack->stack) * stack->size); + } + + stack->stack[stack->pos].flavor = flavor; + stack->stack[stack->pos].data = data; +} + +struct cil_stack_item *cil_stack_pop(struct cil_stack *stack) +{ + if (stack->pos == -1) { + return NULL; + } + + stack->pos--; + return &stack->stack[stack->pos + 1]; +} + +struct cil_stack_item *cil_stack_peek(struct cil_stack *stack) +{ + if (stack->pos < 0) { + return NULL; + } + + return &stack->stack[stack->pos]; +} + +struct cil_stack_item *cil_stack_peek_at(struct cil_stack *stack, int pos) +{ + int peekpos = stack->pos - pos; + + if (peekpos < 0 || peekpos > stack->pos) { + return NULL; + } + + return &stack->stack[peekpos]; +} diff --git a/kernel/libsepol/cil/src/cil_stack.h b/kernel/libsepol/cil/src/cil_stack.h new file mode 100644 index 00000000..0e3eff66 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_stack.h @@ -0,0 +1,63 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_STACK_H_ +#define CIL_STACK_H_ + +struct cil_stack { + struct cil_stack_item *stack; + int size; + int pos; +}; + +struct cil_stack_item { + enum cil_flavor flavor; + void *data; +}; + +#define cil_stack_for_each_starting_at(stack, start, pos, item) \ + for (pos = start, item = cil_stack_peek_at(stack, pos); item != NULL; pos++, item = cil_stack_peek_at(stack, pos)) + +#define cil_stack_for_each(stack, pos, item) cil_stack_for_each_starting_at(stack, 0, pos, item) + + +void cil_stack_init(struct cil_stack **stack); +void cil_stack_destroy(struct cil_stack **stack); + +void cil_stack_empty(struct cil_stack *stack); +int cil_stack_is_empty(struct cil_stack *stack); +int cil_stack_number_of_items(struct cil_stack *stack); + +void cil_stack_push(struct cil_stack *stack, enum cil_flavor flavor, void *data); +struct cil_stack_item *cil_stack_pop(struct cil_stack *stack); +struct cil_stack_item *cil_stack_peek(struct cil_stack *stack); +struct cil_stack_item *cil_stack_peek_at(struct cil_stack *stack, int pos); + + +#endif diff --git a/kernel/libsepol/cil/src/cil_strpool.c b/kernel/libsepol/cil/src/cil_strpool.c new file mode 100644 index 00000000..6e056ae0 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_strpool.c @@ -0,0 +1,123 @@ +/* + * Copyright 2014 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include +#include "cil_mem.h" +#include "cil_strpool.h" + +#include "cil_log.h" +#define CIL_STRPOOL_TABLE_SIZE 1 << 15 + +struct cil_strpool_entry { + char *str; +}; + +static pthread_mutex_t cil_strpool_mutex = PTHREAD_MUTEX_INITIALIZER; +static unsigned int cil_strpool_readers = 0; +static hashtab_t cil_strpool_tab = NULL; + +static unsigned int cil_strpool_hash(hashtab_t h, const_hashtab_key_t key) +{ + const char *p; + size_t size; + unsigned int val; + + val = 0; + size = strlen(key); + for (p = key; ((size_t) (p - key)) < size; p++) + val = + (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); + return val & (h->size - 1); +} + +static int cil_strpool_compare(hashtab_t h __attribute__ ((unused)), const_hashtab_key_t key1, const_hashtab_key_t key2) +{ + return strcmp(key1, key2); +} + +char *cil_strpool_add(const char *str) +{ + struct cil_strpool_entry *strpool_ref = NULL; + + pthread_mutex_lock(&cil_strpool_mutex); + + strpool_ref = hashtab_search(cil_strpool_tab, str); + if (strpool_ref == NULL) { + int rc; + strpool_ref = cil_malloc(sizeof(*strpool_ref)); + strpool_ref->str = cil_strdup(str); + rc = hashtab_insert(cil_strpool_tab, strpool_ref->str, strpool_ref); + if (rc != SEPOL_OK) { + pthread_mutex_unlock(&cil_strpool_mutex); + cil_log(CIL_ERR, "Failed to allocate memory\n"); + exit(1); + } + } + + pthread_mutex_unlock(&cil_strpool_mutex); + return strpool_ref->str; +} + +static int cil_strpool_entry_destroy(hashtab_key_t k __attribute__ ((unused)), hashtab_datum_t d, void *args __attribute__ ((unused))) +{ + struct cil_strpool_entry *strpool_ref = (struct cil_strpool_entry*)d; + free(strpool_ref->str); + free(strpool_ref); + return SEPOL_OK; +} + +void cil_strpool_init(void) +{ + pthread_mutex_lock(&cil_strpool_mutex); + if (cil_strpool_tab == NULL) { + cil_strpool_tab = hashtab_create(cil_strpool_hash, cil_strpool_compare, CIL_STRPOOL_TABLE_SIZE); + if (cil_strpool_tab == NULL) { + pthread_mutex_unlock(&cil_strpool_mutex); + cil_log(CIL_ERR, "Failed to allocate memory\n"); + exit(1); + } + } + cil_strpool_readers++; + pthread_mutex_unlock(&cil_strpool_mutex); +} + +void cil_strpool_destroy(void) +{ + pthread_mutex_lock(&cil_strpool_mutex); + cil_strpool_readers--; + if (cil_strpool_readers == 0) { + ksu_hashtab_map(cil_strpool_tab, cil_strpool_entry_destroy, NULL); + ksu_hashtab_destroy(cil_strpool_tab); + cil_strpool_tab = NULL; + } + pthread_mutex_unlock(&cil_strpool_mutex); +} diff --git a/kernel/libsepol/cil/src/cil_strpool.h b/kernel/libsepol/cil/src/cil_strpool.h new file mode 100644 index 00000000..a61a2d95 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_strpool.h @@ -0,0 +1,38 @@ +/* + * Copyright 2014 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_STRPOOL_H_ +#define CIL_STRPOOL_H_ + +#include + +char *cil_strpool_add(const char *str); +void cil_strpool_init(void); +void cil_strpool_destroy(void); +#endif /* CIL_STRPOOL_H_ */ diff --git a/kernel/libsepol/cil/src/cil_symtab.c b/kernel/libsepol/cil/src/cil_symtab.c new file mode 100644 index 00000000..994b3614 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_symtab.c @@ -0,0 +1,289 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include + +#include +#include +#include + +#include "cil_internal.h" +#include "cil_tree.h" +#include "cil_symtab.h" +#include "cil_mem.h" +#include "cil_strpool.h" +#include "cil_log.h" + +__attribute__((noreturn)) __attribute__((format (printf, 1, 2))) static void cil_symtab_error(const char* msg, ...) +{ + va_list ap; + va_start(ap, msg); + cil_vlog(CIL_ERR, msg, ap); + va_end(ap); + exit(1); +} + +void cil_symtab_init(symtab_t *symtab, unsigned int size) +{ + int rc = ksu_symtab_init(symtab, size); + if (rc != SEPOL_OK) { + cil_symtab_error("Failed to create symtab\n"); + } +} + +void cil_symtab_datum_init(struct cil_symtab_datum *datum) +{ + datum->name = NULL; + datum->fqn = NULL; + datum->symtab = NULL; + cil_list_init(&datum->nodes, CIL_LIST_ITEM); +} + +void cil_symtab_datum_destroy(struct cil_symtab_datum *datum) +{ + cil_list_destroy(&datum->nodes, 0); + cil_symtab_remove_datum(datum); +} + +void cil_symtab_datum_remove_node(struct cil_symtab_datum *datum, struct cil_tree_node *node) +{ + if (datum && datum->nodes != NULL) { + cil_list_remove(datum->nodes, CIL_NODE, node, 0); + if (datum->nodes->head == NULL) { + cil_symtab_datum_destroy(datum); + } + } +} + +/* This both initializes the datum and inserts it into the symtab. + Note that cil_symtab_datum_destroy() is the analog to the initializer portion */ +int cil_symtab_insert(symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node) +{ + int rc = hashtab_insert(symtab->table, key, (hashtab_datum_t)datum); + if (rc == SEPOL_OK) { + datum->name = key; + datum->fqn = key; + datum->symtab = symtab; + symtab->nprim++; + if (node) { + cil_list_append(datum->nodes, CIL_NODE, node); + } + } else if (rc != SEPOL_EEXIST) { + cil_symtab_error("Failed to insert datum into hashtab\n"); + } + + return rc; +} + +void cil_symtab_remove_datum(struct cil_symtab_datum *datum) +{ + symtab_t *symtab = datum->symtab; + + if (symtab == NULL) { + return; + } + + hashtab_remove(symtab->table, datum->name, NULL, NULL); + symtab->nprim--; + datum->symtab = NULL; +} + +int cil_symtab_get_datum(symtab_t *symtab, char *key, struct cil_symtab_datum **datum) +{ + *datum = (struct cil_symtab_datum*)hashtab_search(symtab->table, (hashtab_key_t)key); + if (*datum == NULL) { + return SEPOL_ENOENT; + } + + return SEPOL_OK; +} + +int cil_symtab_map(symtab_t *symtab, + int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), + void *args) +{ + return ksu_hashtab_map(symtab->table, apply, args); +} + +static int __cil_symtab_destroy_helper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, __attribute__((unused)) void *args) +{ + struct cil_symtab_datum *datum = d; + datum->symtab = NULL; + return SEPOL_OK; +} + +void cil_symtab_destroy(symtab_t *symtab) +{ + if (symtab->table != NULL){ + cil_symtab_map(symtab, __cil_symtab_destroy_helper, NULL); + ksu_hashtab_destroy(symtab->table); + symtab->table = NULL; + } +} + +static void cil_complex_symtab_hash(struct cil_complex_symtab_key *ckey, int mask, intptr_t *hash) +{ + intptr_t sum = ckey->key1 + ckey->key2 + ckey->key3 + ckey->key4; + *hash = (intptr_t)((sum >> 2) & mask); +} + +void cil_complex_symtab_init(struct cil_complex_symtab *symtab, unsigned int size) +{ + symtab->htable = cil_calloc(size, sizeof(struct cil_complex_symtab *)); + + symtab->nelems = 0; + symtab->nslots = size; + symtab->mask = size - 1; +} + +int cil_complex_symtab_insert(struct cil_complex_symtab *symtab, + struct cil_complex_symtab_key *ckey, + struct cil_complex_symtab_datum *datum) +{ + intptr_t hash; + struct cil_complex_symtab_node *node = NULL; + struct cil_complex_symtab_node *prev = NULL; + struct cil_complex_symtab_node *curr = NULL; + + node = cil_malloc(sizeof(*node)); + memset(node, 0, sizeof(*node)); + + node->ckey = ckey; + node->datum = datum; + + cil_complex_symtab_hash(ckey, symtab->mask, &hash); + + for (prev = NULL, curr = symtab->htable[hash]; curr != NULL; + prev = curr, curr = curr->next) { + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 == curr->ckey->key2 && + ckey->key3 == curr->ckey->key3 && + ckey->key4 == curr->ckey->key4) { + free(node); + return SEPOL_EEXIST; + } + + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 < curr->ckey->key2) { + break; + } + + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 == curr->ckey->key2 && + ckey->key3 < curr->ckey->key3) { + break; + } + + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 == curr->ckey->key2 && + ckey->key3 == curr->ckey->key3 && + ckey->key4 < curr->ckey->key4) { + break; + } + } + + if (prev != NULL) { + node->next = prev->next; + prev->next = node; + } else { + node->next = symtab->htable[hash]; + symtab->htable[hash] = node; + } + + symtab->nelems++; + + return SEPOL_OK; +} + +void cil_complex_symtab_search(struct cil_complex_symtab *symtab, + struct cil_complex_symtab_key *ckey, + struct cil_complex_symtab_datum **out) +{ + intptr_t hash; + struct cil_complex_symtab_node *curr = NULL; + + cil_complex_symtab_hash(ckey, symtab->mask, &hash); + for (curr = symtab->htable[hash]; curr != NULL; curr = curr->next) { + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 == curr->ckey->key2 && + ckey->key3 == curr->ckey->key3 && + ckey->key4 == curr->ckey->key4) { + *out = curr->datum; + return; + } + + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 < curr->ckey->key2) { + break; + } + + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 == curr->ckey->key2 && + ckey->key3 < curr->ckey->key3) { + break; + } + + if (ckey->key1 == curr->ckey->key1 && + ckey->key2 == curr->ckey->key2 && + ckey->key3 == curr->ckey->key3 && + ckey->key4 < curr->ckey->key4) { + break; + } + } + + *out = NULL; +} + +void cil_complex_symtab_destroy(struct cil_complex_symtab *symtab) +{ + struct cil_complex_symtab_node *curr = NULL; + struct cil_complex_symtab_node *temp = NULL; + unsigned int i; + + if (symtab == NULL) { + return; + } + + for (i = 0; i < symtab->nslots; i++) { + curr = symtab->htable[i]; + while (curr != NULL) { + temp = curr; + curr = curr->next; + free(temp); + } + symtab->htable[i] = NULL; + } + free(symtab->htable); + symtab->htable = NULL; + symtab->nelems = 0; + symtab->nslots = 0; + symtab->mask = 0; +} diff --git a/kernel/libsepol/cil/src/cil_symtab.h b/kernel/libsepol/cil/src/cil_symtab.h new file mode 100644 index 00000000..efb63e7b --- /dev/null +++ b/kernel/libsepol/cil/src/cil_symtab.h @@ -0,0 +1,89 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef __CIL_SYMTAB_H_ +#define __CIL_SYMTAB_H_ + +#include +#include + +#include "cil_tree.h" + +struct cil_symtab_datum { + struct cil_list *nodes; + char *name; + char *fqn; + symtab_t *symtab; +}; + +#define DATUM(d) ((struct cil_symtab_datum *)(d)) +#define NODE(n) ((struct cil_tree_node *)(DATUM(n)->nodes->head->data)) +#define FLAVOR(f) (NODE(f)->flavor) + +struct cil_complex_symtab_key { + intptr_t key1; + intptr_t key2; + intptr_t key3; + intptr_t key4; +}; + +struct cil_complex_symtab_datum { + void *data; +}; + +struct cil_complex_symtab_node { + struct cil_complex_symtab_key *ckey; + struct cil_complex_symtab_datum *datum; + struct cil_complex_symtab_node *next; +}; + +struct cil_complex_symtab { + struct cil_complex_symtab_node **htable; + uint32_t nelems; + uint32_t nslots; + uint32_t mask; +}; + +void cil_symtab_init(symtab_t *symtab, unsigned int size); +void cil_symtab_datum_init(struct cil_symtab_datum *datum); +void cil_symtab_datum_destroy(struct cil_symtab_datum *datum); +void cil_symtab_datum_remove_node(struct cil_symtab_datum *datum, struct cil_tree_node *node); +int cil_symtab_insert(symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node); +void cil_symtab_remove_datum(struct cil_symtab_datum *datum); +int cil_symtab_get_datum(symtab_t *symtab, char *key, struct cil_symtab_datum **datum); +int cil_symtab_map(symtab_t *symtab, + int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), + void *args); +void cil_symtab_destroy(symtab_t *symtab); +void cil_complex_symtab_init(struct cil_complex_symtab *symtab, unsigned int size); +int cil_complex_symtab_insert(struct cil_complex_symtab *symtab, struct cil_complex_symtab_key *ckey, struct cil_complex_symtab_datum *datum); +void cil_complex_symtab_search(struct cil_complex_symtab *symtab, struct cil_complex_symtab_key *ckey, struct cil_complex_symtab_datum **out); +void cil_complex_symtab_destroy(struct cil_complex_symtab *symtab); + +#endif diff --git a/kernel/libsepol/cil/src/cil_tree.c b/kernel/libsepol/cil/src/cil_tree.c new file mode 100644 index 00000000..6376c208 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_tree.c @@ -0,0 +1,337 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include + +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_parser.h" +#include "cil_strpool.h" + +struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **info_kind, uint32_t *hll_line, char **path) +{ + int rc; + + if (!node) { + goto exit; + } + + node = node->parent; + + while (node) { + if (node->flavor == CIL_NODE && node->data == NULL) { + if (node->cl_head && node->cl_head->data == CIL_KEY_SRC_INFO) { + if (!node->cl_head->next || !node->cl_head->next->next || !node->cl_head->next->next->next) { + goto exit; + } + /* Parse Tree */ + *info_kind = node->cl_head->next->data; + rc = cil_string_to_uint32(node->cl_head->next->next->data, hll_line, 10); + if (rc != SEPOL_OK) { + goto exit; + } + *path = node->cl_head->next->next->next->data; + return node; + } + node = node->parent; + } else if (node->flavor == CIL_SRC_INFO) { + /* AST */ + struct cil_src_info *info = node->data; + *info_kind = info->kind; + *hll_line = info->hll_line; + *path = info->path; + return node; + } else { + if (node->flavor == CIL_CALL) { + struct cil_call *call = node->data; + node = NODE(call->macro); + } else if (node->flavor == CIL_BLOCKINHERIT) { + struct cil_blockinherit *inherit = node->data; + node = NODE(inherit->block); + } else { + node = node->parent; + } + } + } + +exit: + *info_kind = NULL; + *hll_line = 0; + *path = NULL; + return NULL; +} + +char *cil_tree_get_cil_path(struct cil_tree_node *node) +{ + char *info_kind; + uint32_t hll_line; + char *path; + + while (node) { + node = cil_tree_get_next_path(node, &info_kind, &hll_line, &path); + if (node && info_kind == CIL_KEY_SRC_CIL) { + return path; + } + } + + return NULL; +} + +__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...) +{ + va_list ap; + + va_start(ap, msg); + cil_vlog(lvl, msg, ap); + va_end(ap); + + if (node) { + char *path = NULL; + uint32_t hll_offset = node->hll_offset; + + path = cil_tree_get_cil_path(node); + + if (path != NULL) { + cil_log(lvl, " at %s:%u", path, node->line); + } + + while (node) { + do { + char *info_kind; + uint32_t hll_line; + + node = cil_tree_get_next_path(node, &info_kind, &hll_line, &path); + if (!node || info_kind == CIL_KEY_SRC_CIL) { + break; + } + if (info_kind == CIL_KEY_SRC_HLL_LMS) { + hll_line += hll_offset - node->hll_offset - 1; + } + + cil_log(lvl," from %s:%u", path, hll_line); + } while (1); + } + } + + cil_log(lvl,"\n"); +} + +int cil_tree_subtree_has_decl(struct cil_tree_node *node) +{ + while (node) { + if (node->flavor >= CIL_MIN_DECLARATIVE) { + return CIL_TRUE; + } + if (node->cl_head != NULL) { + if (cil_tree_subtree_has_decl(node->cl_head)) + return CIL_TRUE; + } + node = node->next; + } + + return CIL_FALSE; +} + +int cil_tree_init(struct cil_tree **tree) +{ + struct cil_tree *new_tree = cil_malloc(sizeof(*new_tree)); + + cil_tree_node_init(&new_tree->root); + + *tree = new_tree; + + return SEPOL_OK; +} + +void cil_tree_destroy(struct cil_tree **tree) +{ + if (tree == NULL || *tree == NULL) { + return; + } + + cil_tree_subtree_destroy((*tree)->root); + free(*tree); + *tree = NULL; +} + +void cil_tree_subtree_destroy(struct cil_tree_node *node) +{ + cil_tree_children_destroy(node); + cil_tree_node_destroy(&node); +} + +void cil_tree_children_destroy(struct cil_tree_node *node) +{ + struct cil_tree_node *curr, *next; + + if (!node) { + return; + } + + curr = node->cl_head; + while (curr) { + next = curr->next; + cil_tree_children_destroy(curr); + cil_tree_node_destroy(&curr); + curr = next; + } + node->cl_head = NULL; + node->cl_tail = NULL; +} + +void cil_tree_node_init(struct cil_tree_node **node) +{ + struct cil_tree_node *new_node = cil_malloc(sizeof(*new_node)); + new_node->cl_head = NULL; + new_node->cl_tail = NULL; + new_node->parent = NULL; + new_node->data = NULL; + new_node->next = NULL; + new_node->flavor = CIL_ROOT; + new_node->line = 0; + new_node->hll_offset = 0; + + *node = new_node; +} + +void cil_tree_node_destroy(struct cil_tree_node **node) +{ + struct cil_symtab_datum *datum; + + if (node == NULL || *node == NULL) { + return; + } + + if ((*node)->flavor >= CIL_MIN_DECLARATIVE) { + datum = (*node)->data; + cil_symtab_datum_remove_node(datum, *node); + if (datum->nodes == NULL) { + cil_destroy_data(&(*node)->data, (*node)->flavor); + } + } else { + cil_destroy_data(&(*node)->data, (*node)->flavor); + } + free(*node); + *node = NULL; +} + +/* Perform depth-first walk of the tree + Parameters: + start_node: root node to start walking from + process_node: function to call when visiting a node + Takes parameters: + node: node being visited + finished: boolean indicating to the tree walker that it should move on from this branch + extra_args: additional data + first_child: Function to call before entering list of children + Takes parameters: + node: node of first child + extra args: additional data + last_child: Function to call when finished with the last child of a node's children + extra_args: any additional data to be passed to the helper functions +*/ + +static int cil_tree_walk_core(struct cil_tree_node *node, + int (*process_node)(struct cil_tree_node *node, uint32_t *finished, void *extra_args), + int (*first_child)(struct cil_tree_node *node, void *extra_args), + int (*last_child)(struct cil_tree_node *node, void *extra_args), + void *extra_args) +{ + int rc = SEPOL_ERR; + + while (node) { + uint32_t finished = CIL_TREE_SKIP_NOTHING; + + if (process_node != NULL) { + rc = (*process_node)(node, &finished, extra_args); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_INFO, "Problem"); + return rc; + } + } + + if (finished & CIL_TREE_SKIP_NEXT) { + return SEPOL_OK; + } + + if (node->cl_head != NULL && !(finished & CIL_TREE_SKIP_HEAD)) { + rc = cil_tree_walk(node, process_node, first_child, last_child, extra_args); + if (rc != SEPOL_OK) { + return rc; + } + } + + node = node->next; + } + + return SEPOL_OK; +} + +int cil_tree_walk(struct cil_tree_node *node, + int (*process_node)(struct cil_tree_node *node, uint32_t *finished, void *extra_args), + int (*first_child)(struct cil_tree_node *node, void *extra_args), + int (*last_child)(struct cil_tree_node *node, void *extra_args), + void *extra_args) +{ + int rc = SEPOL_ERR; + + if (!node || !node->cl_head) { + return SEPOL_OK; + } + + if (first_child != NULL) { + rc = (*first_child)(node->cl_head, extra_args); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_INFO, "Problem"); + return rc; + } + } + + rc = cil_tree_walk_core(node->cl_head, process_node, first_child, last_child, extra_args); + if (rc != SEPOL_OK) { + return rc; + } + + if (last_child != NULL) { + rc = (*last_child)(node->cl_tail, extra_args); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_INFO, "Problem"); + return rc; + } + } + + return SEPOL_OK; +} diff --git a/kernel/libsepol/cil/src/cil_tree.h b/kernel/libsepol/cil/src/cil_tree.h new file mode 100644 index 00000000..5a98da55 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_tree.h @@ -0,0 +1,75 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_TREE_H_ +#define CIL_TREE_H_ + +#include + +#include "cil_flavor.h" +#include "cil_list.h" + +struct cil_tree { + struct cil_tree_node *root; +}; + +struct cil_tree_node { + struct cil_tree_node *parent; + struct cil_tree_node *cl_head; //Head of child_list + struct cil_tree_node *cl_tail; //Tail of child_list + struct cil_tree_node *next; //Each element in the list points to the next element + enum cil_flavor flavor; + uint32_t line; + uint32_t hll_offset; + void *data; +}; + +struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **info_kind, uint32_t *hll_line, char **path); +char *cil_tree_get_cil_path(struct cil_tree_node *node); +__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...); + +int cil_tree_subtree_has_decl(struct cil_tree_node *node); + +int cil_tree_init(struct cil_tree **tree); +void cil_tree_destroy(struct cil_tree **tree); +void cil_tree_subtree_destroy(struct cil_tree_node *node); +void cil_tree_children_destroy(struct cil_tree_node *node); + +void cil_tree_node_init(struct cil_tree_node **node); +void cil_tree_node_destroy(struct cil_tree_node **node); + +//finished values +#define CIL_TREE_SKIP_NOTHING 0 +#define CIL_TREE_SKIP_NEXT 1 +#define CIL_TREE_SKIP_HEAD 2 +#define CIL_TREE_SKIP_ALL (CIL_TREE_SKIP_NOTHING | CIL_TREE_SKIP_NEXT | CIL_TREE_SKIP_HEAD) +int cil_tree_walk(struct cil_tree_node *start_node, int (*process_node)(struct cil_tree_node *node, uint32_t *finished, void *extra_args), int (*first_child)(struct cil_tree_node *node, void *extra_args), int (*last_child)(struct cil_tree_node *node, void *extra_args), void *extra_args); + +#endif /* CIL_TREE_H_ */ + diff --git a/kernel/libsepol/cil/src/cil_verify.c b/kernel/libsepol/cil/src/cil_verify.c new file mode 100644 index 00000000..5e8df839 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_verify.c @@ -0,0 +1,1874 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_log.h" +#include "cil_mem.h" +#include "cil_tree.h" +#include "cil_list.h" +#include "cil_find.h" +#include "cil_stack.h" + +#include "cil_verify.h" + +static int __cil_is_reserved_name(const char *name, enum cil_flavor flavor) +{ + switch (flavor) { + case CIL_BOOL: + case CIL_TUNABLE: + if ((name == CIL_KEY_EQ) || (name == CIL_KEY_NEQ)) + return CIL_TRUE; + break; + case CIL_PERM: + case CIL_MAP_PERM: + case CIL_USER: + case CIL_USERATTRIBUTE: + case CIL_ROLE: + case CIL_ROLEATTRIBUTE: + if (name == CIL_KEY_ALL) + return CIL_TRUE; + break; + case CIL_TYPE: + case CIL_TYPEATTRIBUTE: + case CIL_TYPEALIAS: + if ((name == CIL_KEY_ALL) || (name == CIL_KEY_SELF)) + return CIL_TRUE; + break; + case CIL_CAT: + case CIL_CATSET: + case CIL_CATALIAS: + case CIL_PERMISSIONX: + if ((name == CIL_KEY_ALL) || (name == CIL_KEY_RANGE)) + return CIL_TRUE; + break; + default: + /* All of these are not used in expressions */ + return CIL_FALSE; + break; + } + + /* Everything not under the default case is also checked for these */ + if ((name == CIL_KEY_AND) || (name == CIL_KEY_OR) || (name == CIL_KEY_NOT) || (name == CIL_KEY_XOR)) { + return CIL_TRUE; + } + + return CIL_FALSE; +} + +int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor flavor) +{ + int rc = SEPOL_ERR; + int len; + int i = 0; + + if (name == NULL) { + cil_log(CIL_ERR, "Name is NULL\n"); + goto exit; + } + + len = strlen(name); + if (len >= CIL_MAX_NAME_LENGTH) { + cil_log(CIL_ERR, "Name length greater than max name length of %d", + CIL_MAX_NAME_LENGTH); + rc = SEPOL_ERR; + goto exit; + } + + if (!isalpha(name[0])) { + cil_log(CIL_ERR, "First character in %s is not a letter\n", name); + goto exit; + } + + if (db->qualified_names == CIL_FALSE) { + for (i = 1; i < len; i++) { + if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-') { + cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name); + goto exit; + } + } + } else { + for (i = 1; i < len; i++) { + if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-' && name[i] != '.') { + cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name); + goto exit; + } + } + } + + if (__cil_is_reserved_name(name, flavor)) { + cil_log(CIL_ERR, "Name %s is a reserved word\n", name); + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Invalid name\n"); + return rc; +} + +int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], size_t len) +{ + struct cil_tree_node *c = parse_current; + size_t i = 0; + + while (i < len && c != NULL) { + if ((s[i] & CIL_SYN_STRING) && c->data != NULL && c->cl_head == NULL) { + c = c->next; + i++; + } else if ((s[i] & CIL_SYN_LIST) && c->data == NULL && c->cl_head != NULL) { + c = c->next; + i++; + } else if ((s[i] & CIL_SYN_EMPTY_LIST) && c->data == NULL && c->cl_head == NULL) { + c = c->next; + i++; + } else if ((s[i] & CIL_SYN_N_LISTS) || (s[i] & CIL_SYN_N_STRINGS)) { + while (c != NULL) { + if ((s[i] & CIL_SYN_N_LISTS) && c->data == NULL && c->cl_head != NULL) { + c = c->next; + } else if ((s[i] & CIL_SYN_N_STRINGS) && c->data != NULL && c->cl_head == NULL) { + c = c->next; + } else { + goto exit; + } + } + i++; + break; /* Only CIL_SYN_END allowed after these */ + } else { + goto exit; + } + } + + if (i < len && (s[i] & CIL_SYN_END) && c == NULL) { + return SEPOL_OK; + } + +exit: + cil_log(CIL_ERR, "Invalid syntax\n"); + return SEPOL_ERR; +} + +int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor) +{ + int rc; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + int syntax_len = sizeof(syntax)/sizeof(*syntax); + + switch (op) { + case CIL_NOT: + syntax[2] = CIL_SYN_END; + syntax_len = 3; + break; + case CIL_AND: + case CIL_OR: + case CIL_XOR: + break; + case CIL_EQ: + case CIL_NEQ: + if (expr_flavor != CIL_BOOL && expr_flavor != CIL_TUNABLE ) { + cil_log(CIL_ERR,"Invalid operator (%s) for set expression\n", (char*)current->data); + goto exit; + } + break; + case CIL_ALL: + if (expr_flavor == CIL_BOOL || expr_flavor == CIL_TUNABLE) { + cil_log(CIL_ERR,"Invalid operator (%s) for boolean or tunable expression\n", (char*)current->data); + goto exit; + } + syntax[1] = CIL_SYN_END; + syntax_len = 2; + break; + case CIL_RANGE: + if (expr_flavor != CIL_CAT && expr_flavor != CIL_PERMISSIONX) { + cil_log(CIL_ERR,"Operator (%s) only valid for catset and permissionx expression\n", (char*)current->data); + goto exit; + } + syntax[1] = CIL_SYN_STRING; + syntax[2] = CIL_SYN_STRING; + break; + case CIL_NONE: /* String or List */ + syntax[0] = CIL_SYN_N_STRINGS | CIL_SYN_N_LISTS; + syntax[1] = CIL_SYN_END; + syntax_len = 2; + break; + default: + cil_log(CIL_ERR,"Unexpected value (%s) for expression operator\n", (char*)current->data); + goto exit; + } + + rc = __cil_verify_syntax(current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor) +{ + if (r_flavor == CIL_STRING || r_flavor == CIL_LIST) { + if (l_flavor == CIL_CONS_L1 || l_flavor == CIL_CONS_L2 || l_flavor == CIL_CONS_H1 || l_flavor == CIL_CONS_H2 ) { + cil_log(CIL_ERR, "l1, l2, h1, and h2 cannot be used on the left side with a string or list on the right side\n"); + goto exit; + } else if (l_flavor == CIL_CONS_U3 || l_flavor == CIL_CONS_R3 || l_flavor == CIL_CONS_T3) { + if (expr_flavor != CIL_VALIDATETRANS && expr_flavor != CIL_MLSVALIDATETRANS) { + cil_log(CIL_ERR, "u3, r3, and t3 can only be used with (mls)validatetrans rules\n"); + goto exit; + } + } + } else { + if (r_flavor == CIL_CONS_U1 || r_flavor == CIL_CONS_R1 || r_flavor == CIL_CONS_T1) { + cil_log(CIL_ERR, "u1, r1, and t1 are not allowed on the right side\n"); + goto exit; + } else if (r_flavor == CIL_CONS_U3 || r_flavor == CIL_CONS_R3 || r_flavor == CIL_CONS_T3) { + cil_log(CIL_ERR, "u3, r3, and t3 are not allowed on the right side\n"); + goto exit; + } else if (r_flavor == CIL_CONS_U2) { + if (op != CIL_EQ && op != CIL_NEQ) { + cil_log(CIL_ERR, "u2 on the right side must be used with eq or neq as the operator\n"); + goto exit; + } else if (l_flavor != CIL_CONS_U1) { + cil_log(CIL_ERR, "u2 on the right side must be used with u1 on the left\n"); + goto exit; + } + } else if (r_flavor == CIL_CONS_R2) { + if (l_flavor != CIL_CONS_R1) { + cil_log(CIL_ERR, "r2 on the right side must be used with r1 on the left\n"); + goto exit; + } + } else if (r_flavor == CIL_CONS_T2) { + if (op != CIL_EQ && op != CIL_NEQ) { + cil_log(CIL_ERR, "t2 on the right side must be used with eq or neq as the operator\n"); + goto exit; + } else if (l_flavor != CIL_CONS_T1) { + cil_log(CIL_ERR, "t2 on the right side must be used with t1 on the left\n"); + goto exit; + } + } else if (r_flavor == CIL_CONS_L2) { + if (l_flavor != CIL_CONS_L1 && l_flavor != CIL_CONS_H1) { + cil_log(CIL_ERR, "l2 on the right side must be used with l1 or h1 on the left\n"); + goto exit; + } + } else if (r_flavor == CIL_CONS_H2) { + if (l_flavor != CIL_CONS_L1 && l_flavor != CIL_CONS_L2 && l_flavor != CIL_CONS_H1 ) { + cil_log(CIL_ERR, "h2 on the right side must be used with l1, l2, or h1 on the left\n"); + goto exit; + } + } else if (r_flavor == CIL_CONS_H1) { + if (l_flavor != CIL_CONS_L1) { + cil_log(CIL_ERR, "h1 on the right side must be used with l1 on the left\n"); + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op) +{ + int rc; + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_END, + CIL_SYN_END, + CIL_SYN_END + }; + int syntax_len = sizeof(syntax)/sizeof(*syntax); + + switch (op) { + case CIL_NOT: + syntax[1] = CIL_SYN_LIST; + syntax_len--; + break; + case CIL_AND: + case CIL_OR: + syntax[1] = CIL_SYN_LIST; + syntax[2] = CIL_SYN_LIST; + break; + case CIL_EQ: + case CIL_NEQ: + syntax[1] = CIL_SYN_STRING; + syntax[2] = CIL_SYN_STRING | CIL_SYN_LIST; + break; + case CIL_CONS_DOM: + case CIL_CONS_DOMBY: + case CIL_CONS_INCOMP: + syntax[1] = CIL_SYN_STRING; + syntax[2] = CIL_SYN_STRING; + break; + default: + cil_log(CIL_ERR, "Invalid operator (%s) for constraint expression\n", (char*)current->data); + goto exit; + } + + rc = __cil_verify_syntax(current, syntax, syntax_len); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Invalid constraint syntax\n"); + goto exit; + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +int cil_verify_conditional_blocks(struct cil_tree_node *current) +{ + int found_true = CIL_FALSE; + int found_false = CIL_FALSE; + + if (current->cl_head->data == CIL_KEY_CONDTRUE) { + found_true = CIL_TRUE; + } else if (current->cl_head->data == CIL_KEY_CONDFALSE) { + found_false = CIL_TRUE; + } else { + cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional"); + return SEPOL_ERR; + } + + current = current->next; + if (current != NULL) { + if (current->cl_head->data == CIL_KEY_CONDTRUE) { + if (found_true) { + cil_tree_log(current, CIL_ERR, "More than one true block in conditional"); + return SEPOL_ERR; + } + } else if (current->cl_head->data == CIL_KEY_CONDFALSE) { + if (found_false) { + cil_tree_log(current, CIL_ERR, "More than one false block in conditional"); + return SEPOL_ERR; + } + } else { + cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional"); + return SEPOL_ERR; + } + } + + return SEPOL_OK; +} + +int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name) +{ + struct cil_list_item *item; + struct cil_list *param_list = macro->params; + if (param_list != NULL) { + cil_list_for_each(item, param_list) { + struct cil_param *param = item->data; + if (param->flavor == node->flavor) { + if (param->str == name) { + cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(node), name); + return SEPOL_ERR; + } + } + } + } + return SEPOL_OK; +} + +static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack); + +static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_stack *stack) +{ + struct cil_list_item *item; + int rc = SEPOL_OK; + + if (!expr) { + return SEPOL_OK; + } + + cil_list_for_each(item, expr) { + if (item->flavor == CIL_DATUM) { + struct cil_symtab_datum* datum = item->data; + rc = cil_verify_no_self_reference(FLAVOR(datum), datum, stack); + } else if (item->flavor == CIL_LIST) { + rc = __verify_no_self_reference_in_expr(item->data, stack); + } + if (rc != SEPOL_OK) { + return SEPOL_ERR; + } + } + + return SEPOL_OK; +} + +static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack) +{ + struct cil_stack_item *item; + int i = 0; + int rc = SEPOL_OK; + + cil_stack_for_each(stack, i, item) { + struct cil_symtab_datum *prev = item->data; + if (datum == prev) { + cil_tree_log(NODE(datum), CIL_ERR, "Self-reference found for %s", datum->name); + return SEPOL_ERR; + } + } + + switch (flavor) { + case CIL_USERATTRIBUTE: { + struct cil_userattribute *attr = (struct cil_userattribute *)datum; + cil_stack_push(stack, CIL_DATUM, datum); + rc = __verify_no_self_reference_in_expr(attr->expr_list, stack); + cil_stack_pop(stack); + break; + } + case CIL_ROLEATTRIBUTE: { + struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; + cil_stack_push(stack, CIL_DATUM, datum); + rc = __verify_no_self_reference_in_expr(attr->expr_list, stack); + cil_stack_pop(stack); + break; + } + case CIL_TYPEATTRIBUTE: { + struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; + cil_stack_push(stack, CIL_DATUM, datum); + rc = __verify_no_self_reference_in_expr(attr->expr_list, stack); + cil_stack_pop(stack); + break; + } + case CIL_CATSET: { + struct cil_catset *set = (struct cil_catset *)datum; + cil_stack_push(stack, CIL_DATUM, datum); + rc = __verify_no_self_reference_in_expr(set->cats->datum_expr, stack); + cil_stack_pop(stack); + break; + } + default: + break; + } + + return rc; +} + +int __cil_verify_ranges(struct cil_list *list) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + struct cil_list_item *range = NULL; + + if (list == NULL || list->head == NULL) { + goto exit; + } + + cil_list_for_each(curr, list) { + /* range */ + if (curr->flavor == CIL_LIST) { + range = ((struct cil_list*)curr->data)->head; + if (range == NULL || range->next == NULL || range->next->next != NULL) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR,"Invalid Range syntax\n"); + return rc; +} + +struct cil_args_verify_order { + uint32_t *flavor; +}; + +int __cil_verify_ordered_node_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) +{ + struct cil_args_verify_order *args = extra_args; + uint32_t *flavor = args->flavor; + + if (node->flavor == *flavor) { + if (node->flavor == CIL_SID) { + struct cil_sid *sid = node->data; + if (sid->ordered == CIL_FALSE) { + cil_tree_log(node, CIL_ERR, "SID %s not in sidorder statement", sid->datum.name); + return SEPOL_ERR; + } + } else if (node->flavor == CIL_CLASS) { + struct cil_class *class = node->data; + if (class->ordered == CIL_FALSE) { + cil_tree_log(node, CIL_ERR, "Class %s not in classorder statement", class->datum.name); + return SEPOL_ERR; + } + } else if (node->flavor == CIL_CAT) { + struct cil_cat *cat = node->data; + if (cat->ordered == CIL_FALSE) { + cil_tree_log(node, CIL_ERR, "Category %s not in categoryorder statement", cat->datum.name); + return SEPOL_ERR; + } + } else if (node->flavor == CIL_SENS) { + struct cil_sens *sens = node->data; + if (sens->ordered == CIL_FALSE) { + cil_tree_log(node, CIL_ERR, "Sensitivity %s not in sensitivityorder statement", sens->datum.name); + return SEPOL_ERR; + } + } + } + + return SEPOL_OK; +} + +int __cil_verify_ordered(struct cil_tree_node *current, enum cil_flavor flavor) +{ + struct cil_args_verify_order extra_args; + int rc = SEPOL_ERR; + + extra_args.flavor = &flavor; + + rc = cil_tree_walk(current, __cil_verify_ordered_node_helper, NULL, NULL, &extra_args); + + return rc; +} + +int __cil_verify_initsids(struct cil_list *sids) +{ + int rc = SEPOL_OK; + struct cil_list_item *i; + + if (sids->head == NULL) { + cil_log(CIL_ERR, "At least one initial sid must be defined in the policy\n"); + return SEPOL_ERR; + } + + cil_list_for_each(i, sids) { + struct cil_sid *sid = i->data; + if (sid->context == NULL) { + struct cil_tree_node *node = sid->datum.nodes->head->data; + cil_tree_log(node, CIL_INFO, "No context assigned to SID %s, omitting from policy",sid->datum.name); + } + } + + return rc; +} + +static int __cil_is_cat_in_cats(struct cil_cat *cat, struct cil_cats *cats) +{ + struct cil_list_item *i; + + cil_list_for_each(i, cats->datum_expr) { + struct cil_cat *c = i->data; + if (c == cat) { + return CIL_TRUE; + } + } + + return CIL_FALSE; +} + + +static int __cil_verify_cat_in_cats(struct cil_cat *cat, struct cil_cats *cats) +{ + if (__cil_is_cat_in_cats(cat, cats) != CIL_TRUE) { + cil_log(CIL_ERR, "Failed to find category %s in category list\n", cat->datum.name); + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +static int __cil_verify_cats_associated_with_sens(struct cil_sens *sens, struct cil_cats *cats) +{ + int rc = SEPOL_OK; + struct cil_list_item *i, *j; + + if (!cats) { + return SEPOL_OK; + } + + if (!sens->cats_list) { + cil_log(CIL_ERR, "No categories can be used with sensitivity %s\n", sens->datum.name); + return SEPOL_ERR; + } + + cil_list_for_each(i, cats->datum_expr) { + struct cil_cat *cat = i->data; + int ok = CIL_FALSE; + cil_list_for_each(j, sens->cats_list) { + if (__cil_is_cat_in_cats(cat, j->data) == CIL_TRUE) { + ok = CIL_TRUE; + break; + } + } + + if (ok != CIL_TRUE) { + cil_log(CIL_ERR, "Category %s cannot be used with sensitivity %s\n", + cat->datum.name, sens->datum.name); + rc = SEPOL_ERR; + } + } + + return rc; +} + +static int __cil_verify_levelrange_sensitivity(struct cil_db *db, struct cil_sens *low, struct cil_sens *high) +{ + struct cil_list_item *curr; + int found = CIL_FALSE; + int rc = SEPOL_ERR; + + cil_list_for_each(curr, db->sensitivityorder) { + if (curr->data == low) { + found = CIL_TRUE; + } + + if ((found == CIL_TRUE) && (curr->data == high)) { + break; + } + } + + if (found != CIL_TRUE || curr == NULL) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Sensitivity %s does not dominate %s\n", + high->datum.name, low->datum.name); + return rc; + +} + +static int __cil_verify_levelrange_cats(struct cil_cats *low, struct cil_cats *high) +{ + int rc = SEPOL_ERR; + struct cil_list_item *item; + + if (low == NULL || (low == NULL && high == NULL)) { + return SEPOL_OK; + } + + if (high == NULL) { + rc = SEPOL_ERR; + goto exit; + } + + cil_list_for_each(item, low->datum_expr) { + rc = __cil_verify_cat_in_cats(item->data, high); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Low level category set must be a subset of the high level category set\n"); + return rc; +} + +static int __cil_verify_levelrange(struct cil_db *db, struct cil_levelrange *lr) +{ + int rc = SEPOL_ERR; + + rc = __cil_verify_levelrange_sensitivity(db, lr->low->sens, lr->high->sens); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_verify_levelrange_cats(lr->low->cats, lr->high->cats); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = __cil_verify_cats_associated_with_sens(lr->low->sens, lr->low->cats); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Low level sensitivity and categories are not associated\n"); + goto exit; + } + + rc = __cil_verify_cats_associated_with_sens(lr->high->sens, lr->high->cats); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "High level sensitivity and categories are not associated\n"); + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_verify_named_levelrange(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_levelrange *lr = node->data; + + rc = __cil_verify_levelrange(db, lr); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; +exit: + cil_tree_log(node, CIL_ERR, "Invalid named range"); + return rc; +} + +static int __cil_verify_user_pre_eval(struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_user *user = node->data; + + if (user->dftlevel == NULL) { + cil_log(CIL_ERR, "User %s does not have a default level\n", user->datum.name); + goto exit; + } else if (user->range == NULL) { + cil_log(CIL_ERR, "User %s does not have a level range\n", user->datum.name); + goto exit; + } else if (user->bounds != NULL) { + int steps = 0; + int limit = 2; + struct cil_user *u1 = user; + struct cil_user *u2 = user->bounds; + + while (u2 != NULL) { + if (u1 == u2) { + cil_log(CIL_ERR, "Circular bounds found for user %s\n", u1->datum.name); + goto exit; + } + + if (steps == limit) { + steps = 0; + limit *= 2; + u1 = u2; + } + + u2 = u2->bounds; + steps++; + } + } + + return SEPOL_OK; +exit: + cil_tree_log(node, CIL_ERR, "Invalid user"); + return rc; +} + +static int __cil_verify_user_post_eval(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_user *user = node->data; + + /* Verify user range only if anonymous */ + if (user->range->datum.name == NULL) { + rc = __cil_verify_levelrange(db, user->range); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; +exit: + cil_tree_log(node, CIL_ERR, "Invalid user"); + return rc; +} + +static int __cil_verify_role(struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_role *role = node->data; + int steps = 0; + int limit = 2; + struct cil_role *r1 = role; + struct cil_role *r2 = role->bounds; + + while (r2 != NULL) { + if (r1 == r2) { + cil_log(CIL_ERR, "Circular bounds found for role %s\n", r1->datum.name); + goto exit; + } + + if (steps == limit) { + steps = 0; + limit *= 2; + r1 = r2; + } + + r2 = r2->bounds; + steps++; + } + + return SEPOL_OK; +exit: + cil_tree_log(node, CIL_ERR, "Invalid role"); + return rc; +} + +static int __cil_verify_type(struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_type *type = node->data; + int steps = 0; + int limit = 2; + struct cil_type *t1 = type; + struct cil_type *t2 = type->bounds; + + while (t2 != NULL) { + if (t1 == t2) { + cil_log(CIL_ERR, "Circular bounds found for type %s\n", t1->datum.name); + goto exit; + } + + if (steps == limit) { + steps = 0; + limit *= 2; + t1 = t2; + } + + t2 = t2->bounds; + steps++; + } + + return SEPOL_OK; +exit: + cil_tree_log(node, CIL_ERR, "Invalid type"); + return rc; +} + +static int __cil_verify_context(struct cil_db *db, struct cil_context *ctx) +{ + int rc = SEPOL_ERR; + struct cil_user *user = ctx->user; + struct cil_role *role = ctx->role; + struct cil_type *type = ctx->type; + struct cil_level *user_low = user->range->low; + struct cil_level *user_high = user->range->high; + struct cil_level *ctx_low = ctx->range->low; + struct cil_level *ctx_high = ctx->range->high; + struct cil_list *sensitivityorder = db->sensitivityorder; + struct cil_list_item *curr; + int found = CIL_FALSE; + + if (user->roles != NULL) { + if (!ksu_ebitmap_get_bit(user->roles, role->value)) { + cil_log(CIL_ERR, "Role %s is invalid for user %s\n", ctx->role_str, ctx->user_str); + rc = SEPOL_ERR; + goto exit; + } + } else { + cil_log(CIL_ERR, "No roles given to the user %s\n", ctx->user_str); + rc = SEPOL_ERR; + goto exit; + } + + if (role->types != NULL) { + if (!ksu_ebitmap_get_bit(role->types, type->value)) { + cil_log(CIL_ERR, "Type %s is invalid for role %s\n", ctx->type_str, ctx->role_str); + rc = SEPOL_ERR; + goto exit; + } + } else { + cil_log(CIL_ERR, "No types associated with role %s\n", ctx->role_str); + rc = SEPOL_ERR; + goto exit; + } + + /* Verify range only when anonymous */ + if (ctx->range->datum.name == NULL) { + rc = __cil_verify_levelrange(db, ctx->range); + if (rc != SEPOL_OK) { + goto exit; + } + } + + for (curr = sensitivityorder->head; curr != NULL; curr = curr->next) { + struct cil_sens *sens = curr->data; + + if (found == CIL_FALSE) { + if (sens == user_low->sens) { + found = CIL_TRUE; + } else if (sens == ctx_low->sens) { + cil_log(CIL_ERR, "Range %s is invalid for user %s\n", + ctx->range_str, ctx->user_str); + rc = SEPOL_ERR; + goto exit; + } + } + + if (found == CIL_TRUE) { + if (sens == ctx_high->sens) { + break; + } else if (sens == user_high->sens) { + cil_log(CIL_ERR, "Range %s is invalid for user %s\n", + ctx->range_str, ctx->user_str); + rc = SEPOL_ERR; + goto exit; + } + } + } + + return SEPOL_OK; +exit: + cil_log(CIL_ERR, "Invalid context\n"); + return rc; +} + +static int __cil_verify_named_context(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_context *ctx = node->data; + + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + + return SEPOL_OK; +exit: + cil_tree_log(node, CIL_ERR, "Invalid named context"); + return rc; +} + +/* +static int __cil_verify_rule(struct cil_tree_node *node, struct cil_complex_symtab *symtab) +{ + + int rc = SEPOL_ERR; + struct cil_type_rule *typerule = NULL; + struct cil_roletransition *roletrans = NULL; + struct cil_complex_symtab_key ckey; + + switch (node->flavor) { + case CIL_ROLETRANSITION: { + roletrans = node->data; + ckey.key1 = (intptr_t)roletrans->src; + ckey.key2 = (intptr_t)roletrans->tgt; + ckey.key3 = (intptr_t)roletrans->obj; + ckey.key4 = CIL_ROLETRANSITION; + break; + } + case CIL_TYPE_RULE: { + typerule = node->data; + ckey.key1 = (intptr_t)typerule->src; + ckey.key2 = (intptr_t)typerule->tgt; + ckey.key3 = (intptr_t)typerule->obj; + ckey.key4 = (intptr_t)typerule->rule_kind; + break; + } + default: + break; + } + + + rc = cil_complex_symtab_insert(symtab, &ckey, NULL); + if (rc == SEPOL_EEXIST) { + struct cil_complex_symtab_datum *datum = NULL; + cil_complex_symtab_search(symtab, &ckey, &datum); + if (datum == NULL) { + cil_tree_log(node, CIL_ERR, "Duplicate rule defined"); + rc = SEPOL_ERR; + goto exit; + } + } + + return SEPOL_OK; +exit: + cil_tree_log(node, CIL_ERR, "Invalid rule"); + return rc; +} +*/ + +static int __cil_verify_booleanif_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, __attribute__((unused)) void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_tree_node *rule_node = node; + struct cil_booleanif *bif = node->parent->parent->data; + + switch (rule_node->flavor) { + case CIL_AVRULE: { + struct cil_avrule *avrule = NULL; + avrule = rule_node->data; + if (avrule->rule_kind == CIL_AVRULE_NEVERALLOW) { + if (bif->preserved_tunable) { + cil_tree_log(node, CIL_ERR, "Neverallow found in tunableif block (treated as a booleanif due to preserve-tunables)"); + } else { + cil_tree_log(node, CIL_ERR, "Neverallow found in booleanif block"); + } + rc = SEPOL_ERR; + goto exit; + } + break; + } + case CIL_TYPE_RULE: /* + struct cil_type_rule *typerule = NULL; + struct cil_tree_node *temp_node = NULL; + struct cil_complex_symtab *symtab = extra_args; + struct cil_complex_symtab_key ckey; + struct cil_complex_symtab_datum datum; + typerule = rule_node->data; + + ckey.key1 = (intptr_t)typerule->src; + ckey.key2 = (intptr_t)typerule->tgt; + ckey.key3 = (intptr_t)typerule->obj; + ckey.key4 = (intptr_t)typerule->rule_kind; + + datum.data = node; + + rc = cil_complex_symtab_insert(symtab, &ckey, &datum); + if (rc != SEPOL_OK) { + goto exit; + } + + for (temp_node = rule_node->next; + temp_node != NULL; + temp_node = temp_node->next) { + + if (temp_node->flavor == CIL_TYPE_RULE) { + typerule = temp_node->data; + if ((intptr_t)typerule->src == ckey.key1 && + (intptr_t)typerule->tgt == ckey.key2 && + (intptr_t)typerule->obj == ckey.key3 && + (intptr_t)typerule->rule_kind == ckey.key4) { + cil_log(CIL_ERR, "Duplicate type rule found (line: %d)\n", node->line); + rc = SEPOL_ERR; + goto exit; + } + } + } + break;*/ + + //TODO Fix duplicate type_rule detection + break; + case CIL_CALL: + //Fall through to check content of call + break; + case CIL_TUNABLEIF: + //Fall through + break; + case CIL_NAMETYPETRANSITION: + /* While type transitions with file component are not allowed in + booleanif statements if they don't have "*" as the file. We + can't check that here. Or at least we won't right now. */ + break; + default: { + const char * flavor = cil_node_to_string(node); + if (bif->preserved_tunable) { + cil_tree_log(node, CIL_ERR, "Invalid %s statement in tunableif (treated as a booleanif due to preserve-tunables)", flavor); + } else { + cil_tree_log(node, CIL_ERR, "Invalid %s statement in booleanif", flavor); + } + goto exit; + } + } + + rc = SEPOL_OK; +exit: + return rc; +} + +static int __cil_verify_booleanif(struct cil_tree_node *node, struct cil_complex_symtab *symtab) +{ + int rc = SEPOL_ERR; + struct cil_booleanif *bif = (struct cil_booleanif*)node->data; + struct cil_tree_node *cond_block = node->cl_head; + + while (cond_block != NULL) { + rc = cil_tree_walk(cond_block, __cil_verify_booleanif_helper, NULL, NULL, symtab); + if (rc != SEPOL_OK) { + goto exit; + } + cond_block = cond_block->next; + } + + return SEPOL_OK; +exit: + if (bif->preserved_tunable) { + cil_tree_log(node, CIL_ERR, "Invalid tunableif (treated as a booleanif due to preserve-tunables)"); + } else { + cil_tree_log(node, CIL_ERR, "Invalid booleanif"); + } + return rc; +} + +static int __cil_verify_netifcon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_netifcon *netif = node->data; + struct cil_context *if_ctx = netif->if_context; + struct cil_context *pkt_ctx = netif->packet_context; + + /* Verify only when anonymous */ + if (if_ctx->datum.name == NULL) { + rc = __cil_verify_context(db, if_ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + /* Verify only when anonymous */ + if (pkt_ctx->datum.name == NULL) { + rc = __cil_verify_context(db, pkt_ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid netifcon"); + return rc; +} + +static int __cil_verify_ibendportcon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_ibendportcon *ib_end_port = node->data; + struct cil_context *ctx = ib_end_port->context; + + /* Verify only when anonymous */ + if (!ctx->datum.name) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid ibendportcon"); + return rc; +} + +static int __cil_verify_genfscon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_genfscon *genfs = node->data; + struct cil_context *ctx = genfs->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid genfscon"); + return rc; +} + +static int __cil_verify_filecon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_filecon *file = node->data; + struct cil_context *ctx = file->context; + + if (ctx == NULL) { + rc = SEPOL_OK; + goto exit; + } + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_ERR, "Invalid filecon"); + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + +static int __cil_verify_nodecon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_nodecon *nodecon = node->data; + struct cil_context *ctx = nodecon->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid nodecon"); + return rc; +} + +static int __cil_verify_ibpkeycon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_ibpkeycon *pkey = node->data; + struct cil_context *ctx = pkey->context; + + /* Verify only when anonymous */ + if (!ctx->datum.name) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid ibpkeycon"); + return rc; +} + +static int __cil_verify_portcon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_portcon *port = node->data; + struct cil_context *ctx = port->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid portcon"); + return rc; +} + +static int __cil_verify_pirqcon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_pirqcon *pirq = node->data; + struct cil_context *ctx = pirq->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid pirqcon"); + return rc; +} + +static int __cil_verify_iomemcon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_iomemcon *iomem = node->data; + struct cil_context *ctx = iomem->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid iomemcon"); + return rc; +} + +static int __cil_verify_ioportcon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_ioportcon *ioport = node->data; + struct cil_context *ctx = ioport->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid ioportcon"); + return rc; +} + +static int __cil_verify_pcidevicecon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_pcidevicecon *pcidev = node->data; + struct cil_context *ctx = pcidev->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid pcidevicecon"); + return rc; +} + +static int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_devicetreecon *dt = node->data; + struct cil_context *ctx = dt->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid devicetreecon"); + return rc; +} + +static int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_fsuse *fsuse = node->data; + struct cil_context *ctx = fsuse->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid fsuse"); + return rc; +} + +static int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node *node) +{ + int rc; + struct cil_list *classes = NULL; + struct cil_list_item *item; + struct cil_class *class; + struct cil_symtab_datum *perm_datum; + char *kind_str; + + switch (permx->kind) { + case CIL_PERMX_KIND_IOCTL: + kind_str = CIL_KEY_IOCTL; + break; + default: + cil_tree_log(node, CIL_ERR, "Invalid permissionx kind (%d)", permx->kind); + rc = SEPOL_ERR; + goto exit; + } + + classes = cil_expand_class(permx->obj); + + cil_list_for_each(item, classes) { + class = item->data; + rc = cil_symtab_get_datum(&class->perms, kind_str, &perm_datum); + if (rc == SEPOL_ENOENT) { + if (class->common != NULL) { + rc = cil_symtab_get_datum(&class->common->perms, kind_str, &perm_datum); + } + + if (rc == SEPOL_ENOENT) { + cil_tree_log(node, CIL_ERR, "Invalid permissionx: %s is not a permission of class %s", kind_str, class->datum.name); + rc = SEPOL_ERR; + goto exit; + } + } + } + + rc = SEPOL_OK; + +exit: + if (classes != NULL) { + cil_list_destroy(&classes, CIL_FALSE); + } + + return rc; +} + +static int __cil_verify_avrulex(struct cil_tree_node *node) +{ + struct cil_avrule *avrulex = node->data; + return __cil_verify_permissionx(avrulex->perms.x.permx, node); +} + +static int __cil_verify_class(struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_class *class = node->data; + + if (class->common != NULL) { + struct cil_class *common = class->common; + struct cil_tree_node *common_node = common->datum.nodes->head->data; + struct cil_tree_node *curr_com_perm = NULL; + + for (curr_com_perm = common_node->cl_head; + curr_com_perm != NULL; + curr_com_perm = curr_com_perm->next) { + struct cil_perm *com_perm = curr_com_perm->data; + struct cil_tree_node *curr_class_perm = NULL; + + for (curr_class_perm = node->cl_head; + curr_class_perm != NULL; + curr_class_perm = curr_class_perm->next) { + struct cil_perm *class_perm = curr_class_perm->data; + + if (com_perm->datum.name == class_perm->datum.name) { + cil_log(CIL_ERR, "Duplicate permissions between %s common and class declarations\n", class_perm->datum.name); + goto exit; + } + } + } + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid class"); + return rc; +} + +static int __cil_verify_policycap(struct cil_tree_node *node) +{ + int rc; + struct cil_policycap *polcap = node->data; + + rc = sepol_polcap_getnum((const char*)polcap->datum.name); + if (rc == SEPOL_ERR) { + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid policycap (%s)", (const char*)polcap->datum.name); + return rc; +} + +int __cil_verify_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_ERR; + int *avrule_cnt = 0; + int *handleunknown; + int *mls; + int *nseuserdflt = 0; + int *pass = 0; + struct cil_args_verify *args = extra_args; + struct cil_complex_symtab *csymtab = NULL; + struct cil_db *db = NULL; + + if (node == NULL || extra_args == NULL) { + goto exit; + } + + db = args->db; + avrule_cnt = args->avrule_cnt; + handleunknown = args->handleunknown; + mls = args->mls; + nseuserdflt = args->nseuserdflt; + csymtab = args->csymtab; + pass = args->pass; + + if (node->flavor == CIL_MACRO) { + *finished = CIL_TREE_SKIP_HEAD; + rc = SEPOL_OK; + goto exit; + } else if (node->flavor == CIL_BLOCK) { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + rc = SEPOL_OK; + goto exit; + } + + switch (*pass) { + case 0: { + switch (node->flavor) { + case CIL_USER: + rc = __cil_verify_user_post_eval(db, node); + break; + case CIL_SELINUXUSERDEFAULT: + (*nseuserdflt)++; + rc = SEPOL_OK; + break; + case CIL_ROLE: + rc = __cil_verify_role(node); + break; + case CIL_TYPE: + rc = __cil_verify_type(node); + break; + case CIL_AVRULE: + (*avrule_cnt)++; + rc = SEPOL_OK; + break; + case CIL_HANDLEUNKNOWN: + if (*handleunknown != -1) { + cil_log(CIL_ERR, "Policy can not have more than one handleunknown\n"); + rc = SEPOL_ERR; + } else { + *handleunknown = ((struct cil_handleunknown*)node->data)->handle_unknown; + rc = SEPOL_OK; + } + break; + case CIL_MLS: + if (*mls != -1) { + cil_log(CIL_ERR, "Policy can not have more than one mls\n"); + rc = SEPOL_ERR; + } else { + *mls = ((struct cil_mls*)node->data)->value; + rc = SEPOL_OK; + } + break; + case CIL_ROLETRANSITION: + rc = SEPOL_OK; //TODO __cil_verify_rule doesn't work quite right + //rc = __cil_verify_rule(node, csymtab); + break; + case CIL_TYPE_RULE: + rc = SEPOL_OK; //TODO __cil_verify_rule doesn't work quite right + //rc = __cil_verify_rule(node, csymtab); + break; + case CIL_BOOLEANIF: + rc = __cil_verify_booleanif(node, csymtab); + *finished = CIL_TREE_SKIP_HEAD; + break; + case CIL_LEVELRANGE: + rc = __cil_verify_named_levelrange(db, node); + break; + case CIL_CLASS: + rc = __cil_verify_class(node); + break; + case CIL_POLICYCAP: + rc = __cil_verify_policycap(node); + break; + default: + rc = SEPOL_OK; + break; + } + break; + } + case 1: { + switch (node->flavor) { + case CIL_CONTEXT: + rc = __cil_verify_named_context(db, node); + break; + case CIL_NETIFCON: + rc = __cil_verify_netifcon(db, node); + break; + case CIL_GENFSCON: + rc = __cil_verify_genfscon(db, node); + break; + case CIL_FILECON: + rc = __cil_verify_filecon(db, node); + break; + case CIL_NODECON: + rc = __cil_verify_nodecon(db, node); + break; + case CIL_IBPKEYCON: + rc = __cil_verify_ibpkeycon(db, node); + break; + case CIL_IBENDPORTCON: + rc = __cil_verify_ibendportcon(db, node); + break; + case CIL_PORTCON: + rc = __cil_verify_portcon(db, node); + break; + case CIL_PIRQCON: + rc = __cil_verify_pirqcon(db, node); + break; + case CIL_IOMEMCON: + rc = __cil_verify_iomemcon(db, node); + break; + case CIL_IOPORTCON: + rc = __cil_verify_ioportcon(db, node); + break; + case CIL_PCIDEVICECON: + rc = __cil_verify_pcidevicecon(db, node); + break; + case CIL_DEVICETREECON: + rc = __cil_verify_devicetreecon(db, node); + break; + case CIL_FSUSE: + rc = __cil_verify_fsuse(db, node); + break; + case CIL_AVRULEX: + rc = __cil_verify_avrulex(node); + break; + case CIL_PERMISSIONX: + rc = __cil_verify_permissionx(node->data, node); + break; + case CIL_RANGETRANSITION: + rc = SEPOL_OK; + break; + default: + rc = SEPOL_OK; + break; + } + break; + } + default: + rc = SEPOL_ERR; + } + +exit: + return rc; +} + +static int __add_perm_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct cil_list *perm_list = (struct cil_list *)args; + + cil_list_append(perm_list, CIL_DATUM, d); + + return SEPOL_OK; +} + +static int __cil_verify_classperms(struct cil_list *classperms, + struct cil_symtab_datum *orig, + struct cil_symtab_datum *parent, + struct cil_symtab_datum *cur, + enum cil_flavor flavor, + unsigned steps, unsigned limit) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + + if (classperms == NULL) { + if (flavor == CIL_MAP_PERM) { + cil_tree_log(NODE(cur), CIL_ERR, "Map class %s does not have a classmapping for %s", parent->name, cur->name); + } else { + cil_tree_log(NODE(cur), CIL_ERR, "Classpermission %s does not have a classpermissionset", cur->name); + } + goto exit; + } + + if (steps > 0 && orig == cur) { + if (flavor == CIL_MAP_PERM) { + cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving the map class %s and permission %s", parent->name, cur->name); + } else { + cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving the set %s", cur->name); + } + goto exit; + } else { + steps++; + if (steps > limit) { + steps = 1; + limit *= 2; + orig = cur; + } + } + + cil_list_for_each(curr, classperms) { + if (curr->flavor == CIL_CLASSPERMS) { + struct cil_classperms *cp = curr->data; + if (FLAVOR(cp->class) != CIL_CLASS) { /* MAP */ + struct cil_list_item *i = NULL; + cil_list_for_each(i, cp->perms) { + if (i->flavor != CIL_OP) { + struct cil_perm *cmp = i->data; + rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit); + if (rc != SEPOL_OK) { + goto exit; + } + } else { + enum cil_flavor op = (enum cil_flavor)(uintptr_t)i->data; + if (op == CIL_ALL) { + struct cil_class *mc = cp->class; + struct cil_list *perm_list; + struct cil_list_item *j = NULL; + + cil_list_init(&perm_list, CIL_MAP_PERM); + cil_symtab_map(&mc->perms, __add_perm_to_list, perm_list); + cil_list_for_each(j, perm_list) { + struct cil_perm *cmp = j->data; + rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit); + if (rc != SEPOL_OK) { + cil_list_destroy(&perm_list, CIL_FALSE); + goto exit; + } + } + cil_list_destroy(&perm_list, CIL_FALSE); + } + } + } + } + } else { /* SET */ + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + rc = __cil_verify_classperms(cp->classperms, orig, NULL, &cp->datum, CIL_CLASSPERMISSION, steps, limit); + if (rc != SEPOL_OK) { + goto exit; + } + } + } + + return SEPOL_OK; + +exit: + return SEPOL_ERR; +} + +static int __cil_verify_classpermission(struct cil_tree_node *node) +{ + struct cil_classpermission *cp = node->data; + + return __cil_verify_classperms(cp->classperms, &cp->datum, NULL, &cp->datum, CIL_CLASSPERMISSION, 0, 2); +} + +struct cil_verify_map_args { + struct cil_class *class; + struct cil_tree_node *node; + int rc; +}; + +static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + struct cil_verify_map_args *map_args = args; + struct cil_perm *cmp = (struct cil_perm *)d; + int rc; + + rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &map_args->class->datum, &cmp->datum, CIL_MAP_PERM, 0, 2); + if (rc != SEPOL_OK) { + map_args->rc = rc; + } + + return SEPOL_OK; +} + +static int __cil_verify_map_class(struct cil_tree_node *node) +{ + struct cil_class *mc = node->data; + struct cil_verify_map_args map_args; + + map_args.class = mc; + map_args.node = node; + map_args.rc = SEPOL_OK; + + cil_symtab_map(&mc->perms, __verify_map_perm_classperms, &map_args); + + if (map_args.rc != SEPOL_OK) { + return SEPOL_ERR; + } + + return SEPOL_OK; +} + +int __cil_pre_verify_helper(struct cil_tree_node *node, uint32_t *finished, __attribute__((unused)) void *extra_args) +{ + int rc = SEPOL_OK; + + switch (node->flavor) { + case CIL_MACRO: { + *finished = CIL_TREE_SKIP_HEAD; + break; + } + case CIL_BLOCK: { + struct cil_block *blk = node->data; + if (blk->is_abstract == CIL_TRUE) { + *finished = CIL_TREE_SKIP_HEAD; + } + break; + } + case CIL_USER: + rc = __cil_verify_user_pre_eval(node); + break; + case CIL_MAP_CLASS: + rc = __cil_verify_map_class(node); + break; + case CIL_CLASSPERMISSION: + rc = __cil_verify_classpermission(node); + break; + case CIL_USERATTRIBUTE: + case CIL_ROLEATTRIBUTE: + case CIL_TYPEATTRIBUTE: + case CIL_CATSET: { + struct cil_stack *stack; + cil_stack_init(&stack); + rc = cil_verify_no_self_reference(node->flavor, node->data, stack); + cil_stack_destroy(&stack); + break; + } + default: + rc = SEPOL_OK; + break; + } + + return rc; +} diff --git a/kernel/libsepol/cil/src/cil_verify.h b/kernel/libsepol/cil/src/cil_verify.h new file mode 100644 index 00000000..bb1a072c --- /dev/null +++ b/kernel/libsepol/cil/src/cil_verify.h @@ -0,0 +1,74 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_VERIFY_H_ +#define CIL_VERIFY_H_ + +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_tree.h" +#include "cil_list.h" + +enum cil_syntax { + CIL_SYN_STRING = 1 << 0, + CIL_SYN_LIST = 1 << 1, + CIL_SYN_EMPTY_LIST = 1 << 2, + CIL_SYN_N_LISTS = 1 << 3, + CIL_SYN_N_STRINGS = 1 << 4, + CIL_SYN_END = 1 << 5 +}; + +struct cil_args_verify { + struct cil_db *db; + struct cil_complex_symtab *csymtab; + int *avrule_cnt; + int *handleunknown; + int *mls; + int *nseuserdflt; + int *pass; +}; + +int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor flavor); +int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], size_t len); +int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor); +int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor); +int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op); +int cil_verify_conditional_blocks(struct cil_tree_node *current); +int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name); +int __cil_verify_ranges(struct cil_list *list); +int __cil_verify_ordered_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args); +int __cil_verify_ordered(struct cil_tree_node *current, enum cil_flavor flavor); +int __cil_verify_initsids(struct cil_list *sids); +int __cil_verify_senscat(struct cil_sens *sens, struct cil_cat *cat); +int __cil_verify_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args); +int __cil_pre_verify_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args); + +#endif diff --git a/kernel/libsepol/cil/src/cil_write_ast.c b/kernel/libsepol/cil/src/cil_write_ast.c new file mode 100644 index 00000000..b75784ef --- /dev/null +++ b/kernel/libsepol/cil/src/cil_write_ast.c @@ -0,0 +1,1627 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include + +#include "cil_internal.h" +#include "cil_flavor.h" +#include "cil_list.h" +#include "cil_log.h" +#include "cil_symtab.h" +#include "cil_tree.h" +#include "cil_write_ast.h" + + +static inline const char *datum_or_str(struct cil_symtab_datum *datum, const char *str) +{ + return datum ? datum->fqn : str; +} + +static inline const char *datum_to_str(struct cil_symtab_datum *datum) +{ + return datum ? datum->fqn : ""; +} + +static void write_expr(FILE *out, struct cil_list *expr) +{ + struct cil_list_item *curr; + int notfirst = 0; + + fprintf(out, "("); + cil_list_for_each(curr, expr) { + if (notfirst) + fprintf(out, " "); + else + notfirst = 1; + switch (curr->flavor) { + case CIL_LIST: + write_expr(out, curr->data); + break; + case CIL_STRING: + fprintf(out, "%s", (char *)curr->data); + break; + case CIL_DATUM: + case CIL_TYPE: + case CIL_ROLE: + case CIL_USER: + case CIL_SENS: + case CIL_CAT: + case CIL_BOOL: + case CIL_CLASS: + case CIL_MAP_CLASS: + case CIL_NAME: + fprintf(out, "%s", datum_to_str(curr->data)); + break; + case CIL_OP: { + const char *op_str; + enum cil_flavor op_flavor = (enum cil_flavor)(uintptr_t)curr->data; + switch (op_flavor) { + case CIL_AND: + op_str = CIL_KEY_AND; + break; + case CIL_OR: + op_str = CIL_KEY_OR; + break; + case CIL_NOT: + op_str = CIL_KEY_NOT; + break; + case CIL_ALL: + op_str = CIL_KEY_ALL; + break; + case CIL_EQ: + op_str = CIL_KEY_EQ; + break; + case CIL_NEQ: + op_str = CIL_KEY_NEQ; + break; + case CIL_XOR: + op_str = CIL_KEY_XOR; + break; + case CIL_RANGE: + op_str = CIL_KEY_RANGE; + break; + case CIL_CONS_DOM: + op_str = CIL_KEY_CONS_DOM; + break; + case CIL_CONS_DOMBY: + op_str = CIL_KEY_CONS_DOMBY; + break; + case CIL_CONS_INCOMP: + op_str = CIL_KEY_CONS_INCOMP; + break; + default: + op_str = ""; + break; + } + fprintf(out, "%s", op_str); + break; + } + case CIL_CONS_OPERAND: { + const char *operand_str; + enum cil_flavor operand_flavor = (enum cil_flavor)(uintptr_t)curr->data; + switch (operand_flavor) { + case CIL_CONS_U1: + operand_str = CIL_KEY_CONS_U1; + break; + case CIL_CONS_U2: + operand_str = CIL_KEY_CONS_U2; + break; + case CIL_CONS_U3: + operand_str = CIL_KEY_CONS_U3; + break; + case CIL_CONS_T1: + operand_str = CIL_KEY_CONS_T1; + break; + case CIL_CONS_T2: + operand_str = CIL_KEY_CONS_T2; + break; + case CIL_CONS_T3: + operand_str = CIL_KEY_CONS_T3; + break; + case CIL_CONS_R1: + operand_str = CIL_KEY_CONS_R1; + break; + case CIL_CONS_R2: + operand_str = CIL_KEY_CONS_R2; + break; + case CIL_CONS_R3: + operand_str = CIL_KEY_CONS_R3; + break; + case CIL_CONS_L1: + operand_str = CIL_KEY_CONS_L1; + break; + case CIL_CONS_L2: + operand_str = CIL_KEY_CONS_L2; + break; + case CIL_CONS_H1: + operand_str = CIL_KEY_CONS_H1; + break; + case CIL_CONS_H2: + operand_str = CIL_KEY_CONS_H2; + break; + default: + operand_str = ""; + break; + } + fprintf(out, "%s", operand_str); + break; + } + default: + fprintf(out, ""); + break; + } + } + fprintf(out, ")"); +} + +static void write_node_list(FILE *out, struct cil_tree_node *current) +{ + int notfirst = 0; + + fprintf(out, "("); + while (current) { + if (notfirst) + fprintf(out, " "); + else + notfirst = 1; + + fprintf(out, "%s", datum_to_str(current->data)); + current = current->next; + } + fprintf(out, ")"); +} + +static void write_string_list(FILE *out, struct cil_list *list) +{ + struct cil_list_item *curr; + int notfirst = 0; + + if (!list) { + fprintf(out, "()"); + return; + } + + fprintf(out, "("); + cil_list_for_each(curr, list) { + if (notfirst) + fprintf(out, " "); + else + notfirst = 1; + fprintf(out, "%s", (char*)curr->data); + } + fprintf(out, ")"); +} + +static void write_datum_list(FILE *out, struct cil_list *list) +{ + struct cil_list_item *curr; + int notfirst = 0; + + if (!list) { + fprintf(out, "()"); + return; + } + + fprintf(out, "("); + cil_list_for_each(curr, list) { + if (notfirst) + fprintf(out, " "); + else + notfirst = 1; + fprintf(out, "%s", datum_to_str(curr->data)); + } + fprintf(out, ")"); +} + +static void write_classperms(FILE *out, struct cil_classperms *cp) +{ + if (!cp) { + fprintf(out, "()"); + return; + } + + fprintf(out, "(%s ", datum_or_str(DATUM(cp->class), cp->class_str)); + if (cp->perms) + write_expr(out, cp->perms); + else + write_expr(out, cp->perm_strs); + fprintf(out, ")"); +} + +static void write_classperms_list(FILE *out, struct cil_list *cp_list) +{ + struct cil_list_item *curr; + int notfirst = 0; + int num = 0; + + if (!cp_list) { + fprintf(out, "()"); + return; + } + + cil_list_for_each(curr, cp_list) { + num++; + } + if (num > 1) + fprintf(out, "("); + cil_list_for_each(curr, cp_list) { + if (notfirst) + fprintf(out, " "); + else + notfirst = 1; + if (curr->flavor == CIL_CLASSPERMS) { + write_classperms(out, curr->data); + } else { + struct cil_classperms_set *cp_set = curr->data; + struct cil_classpermission *cp = cp_set->set; + if (cp) { + if (cp->datum.name) + fprintf(out, "%s", datum_to_str(DATUM(cp))); + else + write_classperms_list(out,cp->classperms); + } else { + fprintf(out, "%s", cp_set->set_str); + } + } + } + if (num > 1) + fprintf(out, ")"); +} + +static void write_permx(FILE *out, struct cil_permissionx *permx) +{ + if (permx->datum.name) { + fprintf(out, "%s", datum_to_str(DATUM(permx))); + } else { + fprintf(out, "("); + fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : ""); + fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str)); + write_expr(out, permx->expr_str); + fprintf(out, ")"); + } +} + +static void write_cats(FILE *out, struct cil_cats *cats) +{ + if (cats->datum_expr) { + write_expr(out, cats->datum_expr); + } else { + write_expr(out, cats->str_expr); + } +} + +static void write_level(FILE *out, struct cil_level *level, int print_name) +{ + if (print_name && level->datum.name) { + fprintf(out, "%s", datum_to_str(DATUM(level))); + } else { + fprintf(out, "("); + fprintf(out, "%s", datum_or_str(DATUM(level->sens), level->sens_str)); + if (level->cats) { + fprintf(out, " "); + write_cats(out, level->cats); + } + fprintf(out, ")"); + } +} + +static void write_range(FILE *out, struct cil_levelrange *range, int print_name) +{ + if (print_name && range->datum.name) { + fprintf(out, "%s", datum_to_str(DATUM(range))); + } else { + fprintf(out, "("); + if (range->low) + write_level(out, range->low, CIL_TRUE); + else + fprintf(out, "%s", range->low_str); + fprintf(out, " "); + if (range->high) + write_level(out, range->high, CIL_TRUE); + else + fprintf(out, "%s", range->high_str); + fprintf(out, ")"); + } +} + +static void write_context(FILE *out, struct cil_context *context, int print_name) +{ + if (print_name && context->datum.name) { + fprintf(out, "%s", datum_to_str(DATUM(context))); + } else { + fprintf(out, "("); + fprintf(out, "%s ", datum_or_str(DATUM(context->user), context->user_str)); + fprintf(out, "%s ", datum_or_str(DATUM(context->role), context->role_str)); + fprintf(out, "%s ", datum_or_str(DATUM(context->type), context->type_str)); + if (context->range) + write_range(out, context->range, CIL_TRUE); + else + fprintf(out, "%s", context->range_str); + fprintf(out, ")"); + } +} + +static void write_ipaddr(FILE *out, struct cil_ipaddr *ipaddr) +{ + if (ipaddr->datum.name) { + fprintf(out, "%s", datum_to_str(DATUM(ipaddr))); + } else { + char buf[256]; + if (inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256) == NULL) + strcpy(buf, ""); + fprintf(out, "(%s)", buf); + } +} + +static void write_constrain(FILE *out, struct cil_constrain *cons) +{ + write_classperms_list(out, cons->classperms); + fprintf(out, " "); + if (cons->datum_expr) + write_expr(out, cons->datum_expr); + else + write_expr(out, cons->str_expr); +} + +static void write_call_args(FILE *out, struct cil_list *args) +{ + struct cil_list_item *item; + int notfirst = 0; + + fprintf(out, "("); + cil_list_for_each(item, args) { + struct cil_args* arg = item->data; + enum cil_flavor arg_flavor = arg->flavor; + if (notfirst) + fprintf(out, " "); + else + notfirst = 1; + switch (arg_flavor) { + case CIL_TYPE: + case CIL_ROLE: + case CIL_USER: + case CIL_SENS: + case CIL_CAT: + case CIL_BOOL: + case CIL_CLASS: + case CIL_MAP_CLASS: + case CIL_NAME: { + fprintf(out, "%s", datum_or_str(arg->arg, arg->arg_str)); + break; + } + case CIL_CATSET: { + if (arg->arg) { + struct cil_catset *catset = (struct cil_catset *)arg->arg; + write_cats(out, catset->cats); + } else { + fprintf(out, "%s", arg->arg_str); + } + break; + } + case CIL_LEVEL: { + if (arg->arg) { + struct cil_level *level = (struct cil_level *)arg->arg; + write_level(out, level, CIL_TRUE); + } else { + fprintf(out, "%s", arg->arg_str); + } + break; + } + case CIL_LEVELRANGE: { + if (arg->arg) { + struct cil_levelrange *range = (struct cil_levelrange *)arg->arg; + write_range(out, range, CIL_TRUE); + } else { + fprintf(out, "%s", arg->arg_str); + } + break; + } + case CIL_IPADDR: { + if (arg->arg) { + struct cil_ipaddr *addr = (struct cil_ipaddr *)arg->arg; + write_ipaddr(out, addr); + } else { + fprintf(out, "%s", arg->arg_str); + } + break; + } + case CIL_CLASSPERMISSION: { + if (arg->arg) { + struct cil_classpermission *cp = (struct cil_classpermission *)arg->arg; + if (cp->datum.name) + fprintf(out, "%s", datum_to_str(DATUM(cp))); + else + write_classperms_list(out, cp->classperms); + } else { + fprintf(out, "%s", arg->arg_str); + } + break; + } + default: + fprintf(out, "", datum_or_str(arg->arg, arg->arg_str)); + break; + } + } + fprintf(out, ")"); +} + +static void write_call_args_tree(FILE *out, struct cil_tree_node *arg_node) +{ + while (arg_node) { + if (arg_node->data) { + fprintf(out, "%s", (char *)arg_node->data); + } else if (arg_node->cl_head) { + fprintf(out, "("); + write_call_args_tree(out, arg_node->cl_head); + fprintf(out, ")"); + } + if (arg_node->next) + fprintf(out, " "); + arg_node = arg_node->next; + } +} + +static const char *macro_param_flavor_to_string(enum cil_flavor flavor) +{ + const char *str; + switch(flavor) { + case CIL_TYPE: + str = CIL_KEY_TYPE; + break; + case CIL_ROLE: + str = CIL_KEY_ROLE; + break; + case CIL_USER: + str = CIL_KEY_USER; + break; + case CIL_SENS: + str = CIL_KEY_SENSITIVITY; + break; + case CIL_CAT: + str = CIL_KEY_CATEGORY; + break; + case CIL_CATSET: + str = CIL_KEY_CATSET; + break; + case CIL_LEVEL: + str = CIL_KEY_LEVEL; + break; + case CIL_LEVELRANGE: + str = CIL_KEY_LEVELRANGE; + break; + case CIL_CLASS: + str = CIL_KEY_CLASS; + break; + case CIL_IPADDR: + str = CIL_KEY_IPADDR; + break; + case CIL_MAP_CLASS: + str = CIL_KEY_MAP_CLASS; + break; + case CIL_CLASSPERMISSION: + str = CIL_KEY_CLASSPERMISSION; + break; + case CIL_BOOL: + str = CIL_KEY_BOOL; + break; + case CIL_STRING: + str = CIL_KEY_STRING; + break; + case CIL_NAME: + str = CIL_KEY_NAME; + break; + default: + str = ""; + break; + } + return str; +} + +static void cil_write_src_info_node(FILE *out, struct cil_tree_node *node) +{ + struct cil_src_info *info = node->data; + if (info->kind == CIL_KEY_SRC_CIL || info->kind == CIL_KEY_SRC_HLL_LMS) { + fprintf(out, ";;* lms %u %s\n", info->hll_line, info->path); + } else if (info->kind == CIL_KEY_SRC_HLL_LMX) { + fprintf(out, ";;* lmx %u %s\n", info->hll_line, info->path); + } else { + fprintf(out, ";;* %u %s\n", info->hll_line, info->path); + } +} + +void cil_write_ast_node(FILE *out, struct cil_tree_node *node) +{ + if (!node->data) { + return; + } + + switch(node->flavor) { + case CIL_NODE: { + fprintf(out, "%s\n", (char *)node->data); + break; + } + case CIL_BLOCK: { + struct cil_block *block = node->data; + fprintf(out, "(block %s", datum_to_str(DATUM(block))); + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_BLOCKINHERIT: { + struct cil_blockinherit *inherit = node->data; + fprintf(out, "(blockinherit %s)\n", datum_or_str(DATUM(inherit->block), inherit->block_str)); + break; + } + case CIL_IN: { + struct cil_in *in = node->data; + fprintf(out, "(in %s", in->block_str); + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_OPTIONAL: { + struct cil_optional *optional = node->data; + fprintf(out, "(optional %s", datum_to_str(DATUM(optional))); + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_BOOLEANIF: { + struct cil_booleanif *bif = node->data; + fprintf(out, "(booleanif "); + if (bif->datum_expr) + write_expr(out, bif->datum_expr); + else + write_expr(out, bif->str_expr); + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_TUNABLEIF: { + struct cil_tunableif *tif = node->data; + fprintf(out, "(tunableif "); + if (tif->datum_expr) + write_expr(out, tif->datum_expr); + else + write_expr(out, tif->str_expr); + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_CONDBLOCK: { + struct cil_condblock *cb = node->data; + fprintf(out, "(%s", cb->flavor == CIL_CONDTRUE ? "true" : "false"); + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_MACRO: { + struct cil_macro *macro = node->data; + struct cil_list_item *curr; + fprintf(out, "(macro %s (", datum_to_str(DATUM(macro))); + if (macro->params) { + cil_list_for_each(curr, macro->params) { + struct cil_param *param = curr->data; + fprintf(out, "(%s %s)", macro_param_flavor_to_string(param->flavor), param->str); + } + } + fprintf(out, ")"); + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_CALL: { + struct cil_call *call = node->data; + fprintf(out, "(call %s", datum_or_str(DATUM(call->macro), call->macro_str)); + if (call->args) { + fprintf(out, " "); + write_call_args(out, call->args); + } else if (call->args_tree) { + fprintf(out, " "); + write_call_args_tree(out, call->args_tree->root); + } + if (!node->cl_head) + fprintf(out, ")"); + fprintf(out, "\n"); + break; + } + case CIL_BLOCKABSTRACT: { + struct cil_blockabstract *abstract = node->data; + fprintf(out, "(blockabstract %s)\n", abstract->block_str); + break; + } + case CIL_MLS: { + struct cil_mls *mls = node->data; + fprintf(out, "(mls %s)\n", mls->value ? "true" : "false"); + break; + } + case CIL_HANDLEUNKNOWN: { + struct cil_handleunknown *unknown = node->data; + fprintf(out, "(handleunknown "); + if (unknown->handle_unknown == SEPOL_ALLOW_UNKNOWN) + fprintf(out, "%s", CIL_KEY_HANDLEUNKNOWN_ALLOW); + else if (unknown->handle_unknown == SEPOL_DENY_UNKNOWN) + fprintf(out, "%s", CIL_KEY_HANDLEUNKNOWN_DENY); + else if (unknown->handle_unknown == SEPOL_REJECT_UNKNOWN) + fprintf(out, "%s", CIL_KEY_HANDLEUNKNOWN_REJECT); + else + fprintf(out, ""); + fprintf(out, ")\n"); + break; + } + case CIL_DEFAULTUSER: { + struct cil_default *def = node->data; + fprintf(out, "(defaultuser "); + if (def->class_datums) + write_datum_list(out, def->class_datums); + else + write_string_list(out, def->class_strs); + if (def->object == CIL_DEFAULT_SOURCE) + fprintf(out, " source"); + else if (def->object == CIL_DEFAULT_TARGET) + fprintf(out, " target"); + else + fprintf(out, " "); + fprintf(out, ")\n"); + break; + } + case CIL_DEFAULTROLE: { + struct cil_default *def = node->data; + fprintf(out, "(defaultrole "); + if (def->class_datums) + write_datum_list(out, def->class_datums); + else + write_string_list(out, def->class_strs); + if (def->object == CIL_DEFAULT_SOURCE) + fprintf(out, " source"); + else if (def->object == CIL_DEFAULT_TARGET) + fprintf(out, " target"); + else + fprintf(out, " "); + fprintf(out, ")\n"); + break; + } + case CIL_DEFAULTTYPE: { + struct cil_default *def = node->data; + fprintf(out, "(defaulttype "); + if (def->class_datums) + write_datum_list(out, def->class_datums); + else + write_string_list(out, def->class_strs); + if (def->object == CIL_DEFAULT_SOURCE) + fprintf(out, " source"); + else if (def->object == CIL_DEFAULT_TARGET) + fprintf(out, " target"); + else + fprintf(out, " "); + fprintf(out, ")\n"); + break; + } + case CIL_DEFAULTRANGE: { + struct cil_defaultrange *def = node->data; + fprintf(out, "(defaultrange "); + if (def->class_datums) + write_datum_list(out, def->class_datums); + else + write_string_list(out, def->class_strs); + if (def->object_range == CIL_DEFAULT_SOURCE_LOW) + fprintf(out, " source low"); + else if (def->object_range == CIL_DEFAULT_SOURCE_HIGH) + fprintf(out, " source high"); + else if (def->object_range == CIL_DEFAULT_SOURCE_LOW_HIGH) + fprintf(out, " source low-high"); + else if (def->object_range == CIL_DEFAULT_TARGET_LOW) + fprintf(out, " target low"); + else if (def->object_range == CIL_DEFAULT_TARGET_HIGH) + fprintf(out, " target high"); + else if (def->object_range == CIL_DEFAULT_TARGET_LOW_HIGH) + fprintf(out, " target low-high"); + else + fprintf(out, " "); + fprintf(out, ")\n"); + break; + } + case CIL_CLASS: { + struct cil_class *class = node->data; + fprintf(out, "(class %s ", datum_to_str(DATUM(class))); + write_node_list(out, node->cl_head); + fprintf(out, ")\n"); + break; + } + case CIL_CLASSORDER: { + struct cil_classorder *classorder = node->data; + fprintf(out, "(classorder "); + write_string_list(out, classorder->class_list_str); + fprintf(out, ")\n"); + break; + } + case CIL_COMMON: { + struct cil_class *common = node->data; + fprintf(out, "(common %s ", datum_to_str(DATUM(common))); + write_node_list(out, node->cl_head); + fprintf(out, ")\n"); + break; + } + case CIL_CLASSCOMMON: { + struct cil_classcommon *cc = node->data; + fprintf(out, "(classcommon %s %s)\n", cc->class_str, cc->common_str); + break; + } + case CIL_CLASSPERMISSION: { + struct cil_classpermission *cp = node->data; + fprintf(out, "(classpermission %s)\n", datum_to_str(DATUM(cp))); + break; + } + case CIL_CLASSPERMISSIONSET: { + struct cil_classpermissionset *cps = node->data; + fprintf(out, "(classpermissionset %s ", cps->set_str); + write_classperms_list(out, cps->classperms); + fprintf(out, ")\n"); + break; + } + case CIL_MAP_CLASS: { + struct cil_class *map = node->data; + fprintf(out, "(classmap %s ", datum_to_str(DATUM(map))); + write_node_list(out, node->cl_head); + fprintf(out, ")\n"); + break; + } + case CIL_CLASSMAPPING: { + struct cil_classmapping *mapping = node->data; + fprintf(out, "(classmapping %s %s ", mapping->map_class_str, mapping->map_perm_str); + write_classperms_list(out, mapping->classperms); + fprintf(out, ")\n"); + break; + } + case CIL_PERMISSIONX: { + struct cil_permissionx *permx = node->data; + fprintf(out, "(permissionx %s (", datum_to_str(DATUM(permx))); + fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : ""); + fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str)); + write_expr(out, permx->expr_str); + fprintf(out, "))\n"); + break; + } + case CIL_SID: { + struct cil_sid *sid = node->data; + fprintf(out, "(sid %s)\n", datum_to_str(DATUM(sid))); + break; + } + case CIL_SIDCONTEXT: { + struct cil_sidcontext *sidcon = node->data; + fprintf(out, "(sidcontext %s ", sidcon->sid_str); + if (sidcon->context) + write_context(out, sidcon->context, CIL_TRUE); + else + fprintf(out, "%s", sidcon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_SIDORDER: { + struct cil_sidorder *sidorder = node->data; + fprintf(out, "(sidorder "); + write_string_list(out, sidorder->sid_list_str); + fprintf(out, ")\n"); + break; + } + case CIL_BOOL: { + struct cil_bool *boolean = node->data; + fprintf(out, "(boolean %s %s)\n", datum_to_str(DATUM(boolean)), boolean->value ? "true" : "false"); + break; + } + case CIL_TUNABLE: { + struct cil_tunable *tunable = node->data; + fprintf(out, "(tunable %s %s)\n", datum_to_str(DATUM(tunable)), tunable->value ? "true" : "false"); + break; + } + case CIL_SENS: { + struct cil_sens *sens = node->data; + fprintf(out, "(sensitivity %s)\n", datum_to_str(DATUM(sens))); + break; + } + case CIL_SENSALIAS: { + struct cil_alias *alias = node->data; + fprintf(out, "(sensitivityalias %s)\n", datum_to_str(DATUM(alias))); + break; + } + case CIL_SENSALIASACTUAL: { + struct cil_aliasactual *aliasactual = node->data; + fprintf(out, "(sensitivityaliasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str); + break; + } + case CIL_CAT: { + struct cil_cat *cat = node->data; + fprintf(out, "(category %s)\n", datum_to_str(DATUM(cat))); + break; + } + case CIL_CATALIAS: { + struct cil_alias *alias = node->data; + fprintf(out, "(categoryalias %s)\n", datum_to_str(DATUM(alias))); + break; + } + case CIL_CATALIASACTUAL: { + struct cil_aliasactual *aliasactual = node->data; + fprintf(out, "(categoryaliasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str); + break; + } + case CIL_CATSET: { + struct cil_catset *catset = node->data; + fprintf(out, "(categoryset %s ", datum_to_str(DATUM(catset))); + write_cats(out, catset->cats); + fprintf(out, ")\n"); + break; + } + case CIL_CATORDER: { + struct cil_catorder *catorder = node->data; + fprintf(out, "(categoryorder "); + write_string_list(out, catorder->cat_list_str); + fprintf(out, ")\n"); + break; + } + case CIL_SENSCAT: { + struct cil_senscat *senscat = node->data; + fprintf(out, "(sensitivitycategory "); + fprintf(out, "%s ", senscat->sens_str); + write_cats(out, senscat->cats); + fprintf(out, ")\n"); + break; + } + case CIL_SENSITIVITYORDER: { + struct cil_sensorder *sensorder = node->data; + fprintf(out, "(sensitivityorder "); + write_string_list(out, sensorder->sens_list_str); + fprintf(out, ")\n"); + break; + } + case CIL_LEVEL: { + struct cil_level *level = node->data; + fprintf(out, "(level %s ", datum_to_str(&level->datum)); + write_level(out, level, CIL_FALSE); + fprintf(out, ")\n"); + break; + } + case CIL_LEVELRANGE: { + struct cil_levelrange *lvlrange = node->data; + fprintf(out, "(levelrange %s ", datum_to_str(DATUM(lvlrange))); + write_range(out, lvlrange, CIL_FALSE); + fprintf(out, ")\n"); + break; + } + case CIL_USER: { + struct cil_user *user = node->data; + fprintf(out, "(user %s)\n", datum_to_str(DATUM(user))); + break; + } + case CIL_USERATTRIBUTE: { + struct cil_userattribute *attr = node->data; + fprintf(out, "(userattribute %s)\n", datum_to_str(DATUM(attr))); + break; + } + case CIL_USERATTRIBUTESET: { + struct cil_userattributeset *attr = node->data; + fprintf(out, "(userattributeset %s ", attr->attr_str); + if (attr->datum_expr) + write_expr(out, attr->datum_expr); + else + write_expr(out, attr->str_expr); + fprintf(out, ")\n"); + break; + } + case CIL_USERROLE: { + struct cil_userrole *userrole = node->data; + fprintf(out, "(userrole "); + fprintf(out, "%s ", datum_or_str(userrole->user, userrole->user_str)); + fprintf(out, "%s", datum_or_str(userrole->role, userrole->role_str)); + fprintf(out, ")\n"); + break; + } + case CIL_USERLEVEL: { + struct cil_userlevel *userlevel = node->data; + fprintf(out, "(userlevel %s ", userlevel->user_str); + if (userlevel->level) + write_level(out, userlevel->level, CIL_TRUE); + else + fprintf(out, "%s", userlevel->level_str); + fprintf(out, ")\n"); + break; + } + case CIL_USERRANGE: { + struct cil_userrange *userrange = node->data; + fprintf(out, "(userrange %s ", userrange->user_str); + if (userrange->range) + write_range(out, userrange->range, CIL_TRUE); + else + fprintf(out, "%s", userrange->range_str); + fprintf(out, ")\n"); + break; + } + case CIL_USERBOUNDS: { + struct cil_bounds *bounds = node->data; + fprintf(out, "(userbounds %s %s)\n", bounds->parent_str, bounds->child_str); + break; + } + case CIL_USERPREFIX: { + struct cil_userprefix *prefix = node->data; + fprintf(out, "(userprefix "); + fprintf(out, "%s ", datum_or_str(DATUM(prefix->user), prefix->user_str)); + fprintf(out, "%s)\n", prefix->prefix_str); + break; + } + case CIL_SELINUXUSER: { + struct cil_selinuxuser *selinuxuser = node->data; + fprintf(out, "(selinuxuser %s ", selinuxuser->name_str); + fprintf(out, "%s ", datum_or_str(DATUM(selinuxuser->user), selinuxuser->user_str)); + if (selinuxuser->range) + write_range(out, selinuxuser->range, CIL_TRUE); + else + fprintf(out, "%s", selinuxuser->range_str); + fprintf(out, ")\n"); + break; + } + case CIL_SELINUXUSERDEFAULT: { + struct cil_selinuxuser *selinuxuser = node->data; + fprintf(out, "(selinuxuserdefault "); + fprintf(out, "%s ", datum_or_str(DATUM(selinuxuser->user), selinuxuser->user_str)); + if (selinuxuser->range) + write_range(out, selinuxuser->range, CIL_TRUE); + else + fprintf(out, "%s", selinuxuser->range_str); + fprintf(out, ")\n"); + break; + } + case CIL_ROLE: { + fprintf(out, "(role %s)\n", datum_to_str(node->data)); + break; + } + case CIL_ROLEATTRIBUTE: { + fprintf(out, "(roleattribute %s)\n", datum_to_str(node->data)); + break; + } + case CIL_ROLEATTRIBUTESET: { + struct cil_roleattributeset *attr = node->data; + fprintf(out, "(roleattributeset %s ", attr->attr_str); + if (attr->datum_expr) + write_expr(out, attr->datum_expr); + else + write_expr(out, attr->str_expr); + fprintf(out, ")\n"); + break; + } + case CIL_ROLETYPE: { + struct cil_roletype *roletype = node->data; + fprintf(out, "(roletype "); + fprintf(out, "%s ", datum_or_str(DATUM(roletype->role), roletype->role_str)); + fprintf(out, "%s", datum_or_str(DATUM(roletype->type), roletype->type_str)); + fprintf(out, ")\n"); + break; + } + case CIL_ROLEBOUNDS: { + struct cil_bounds *bnds = node->data; + fprintf(out, "(rolebounds %s %s)\n", bnds->parent_str, bnds->child_str); + break; + } + case CIL_TYPE: { + fprintf(out, "(type %s)\n", datum_to_str(node->data)); + break; + } + case CIL_TYPEALIAS: { + fprintf(out, "(typealias %s)\n", datum_to_str(node->data)); + break; + } + case CIL_TYPEALIASACTUAL: { + struct cil_aliasactual *aliasactual = node->data; + fprintf(out, "(typealiasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str); + break; + } + case CIL_TYPEATTRIBUTE: { + fprintf(out, "(typeattribute %s)\n", datum_to_str(node->data)); + break; + } + case CIL_TYPEATTRIBUTESET: { + struct cil_typeattributeset *attr = node->data; + fprintf(out, "(typeattributeset %s ", attr->attr_str); + if (attr->datum_expr) + write_expr(out, attr->datum_expr); + else + write_expr(out, attr->str_expr); + fprintf(out, ")\n"); + break; + } + case CIL_EXPANDTYPEATTRIBUTE: { + struct cil_expandtypeattribute *attr = node->data; + fprintf(out, "(expandtypeattribute "); + if (attr->attr_datums) + write_expr(out, attr->attr_datums); + else + write_expr(out, attr->attr_strs); + fprintf(out, " %s)\n", attr->expand ? "true" : "false"); + break; + } + case CIL_TYPEPERMISSIVE: { + struct cil_typepermissive *tp = node->data; + fprintf(out, "(typepermissive "); + fprintf(out, "%s", datum_or_str(DATUM(tp->type), tp->type_str)); + fprintf(out, ")\n"); + break; + } + case CIL_TYPEBOUNDS: { + struct cil_bounds *bounds = node->data; + fprintf(out, "(typebounds %s %s)\n", bounds->parent_str, bounds->child_str); + break; + } + case CIL_ROLEALLOW: { + struct cil_roleallow *roleallow = node->data; + fprintf(out, "(roleallow "); + fprintf(out, "%s ", datum_or_str(DATUM(roleallow->src), roleallow->src_str)); + fprintf(out, "%s", datum_or_str(DATUM(roleallow->tgt), roleallow->tgt_str)); + fprintf(out, ")\n"); + break; + } + case CIL_ROLETRANSITION: { + struct cil_roletransition *roletrans = node->data; + fprintf(out, "(roletransition "); + fprintf(out, "%s ", datum_or_str(DATUM(roletrans->src), roletrans->src_str)); + fprintf(out, "%s ", datum_or_str(DATUM(roletrans->tgt), roletrans->tgt_str)); + fprintf(out, "%s ", datum_or_str(DATUM(roletrans->obj), roletrans->obj_str)); + fprintf(out, "%s", datum_or_str(DATUM(roletrans->result), roletrans->result_str)); + fprintf(out, ")\n"); + break; + } + case CIL_AVRULE: { + struct cil_avrule *rule = node->data; + if (rule->rule_kind == AVRULE_ALLOWED) + fprintf(out, "(allow "); + else if (rule->rule_kind == AVRULE_AUDITALLOW) + fprintf(out, "(auditallow "); + else if (rule->rule_kind == AVRULE_DONTAUDIT) + fprintf(out, "(dontaudit "); + else if (rule->rule_kind == AVRULE_NEVERALLOW) + fprintf(out, "(neverallow "); + else + fprintf(out, "( "); + + fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); + write_classperms_list(out, rule->perms.classperms); + fprintf(out, ")\n"); + break; + } + case CIL_AVRULEX: { + struct cil_avrule *rule = node->data; + if (rule->rule_kind == AVRULE_ALLOWED) + fprintf(out, "(allowx "); + else if (rule->rule_kind == AVRULE_AUDITALLOW) + fprintf(out, "(auditallowx "); + else if (rule->rule_kind == AVRULE_DONTAUDIT) + fprintf(out, "(dontauditx "); + else if (rule->rule_kind == AVRULE_NEVERALLOW) + fprintf(out, "(neverallowx "); + else + fprintf(out, "( "); + fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); + if (rule->perms.x.permx_str) { + fprintf(out, "%s",rule->perms.x.permx_str); + } else { + write_permx(out, rule->perms.x.permx); + } + fprintf(out, ")\n"); + break; + } + case CIL_TYPE_RULE: { + struct cil_type_rule *rule = node->data; + if (rule->rule_kind == AVRULE_TRANSITION) + fprintf(out, "(typetransition "); + else if (rule->rule_kind == AVRULE_MEMBER) + fprintf(out, "(typemember "); + else if (rule->rule_kind == AVRULE_CHANGE) + fprintf(out, "(typechange "); + else + fprintf(out, "( "); + fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str)); + fprintf(out, "%s", datum_or_str(DATUM(rule->result), rule->result_str)); + fprintf(out, ")\n"); + break; + } + case CIL_NAMETYPETRANSITION: { + struct cil_nametypetransition *rule = node->data; + fprintf(out, "(typetransition "); + fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str)); + fprintf(out, "\"%s\" ", datum_or_str(DATUM(rule->name), rule->name_str)); + fprintf(out, "%s", datum_or_str(DATUM(rule->result), rule->result_str)); + fprintf(out, ")\n"); + break; + } + case CIL_RANGETRANSITION: { + struct cil_rangetransition *rule = node->data; + fprintf(out, "(rangetransition "); + fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->exec), rule->exec_str)); + fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str)); + if (rule->range) + write_range(out, rule->range, CIL_TRUE); + else + fprintf(out, "%s", rule->range_str); + fprintf(out, ")\n"); + break; + } + case CIL_CONSTRAIN: { + struct cil_constrain *cons = node->data; + fprintf(out, "(constrain "); + write_constrain(out, cons); + fprintf(out, ")\n"); + break; + } + case CIL_MLSCONSTRAIN: { + struct cil_constrain *cons = node->data; + fprintf(out, "(mlsconstrain "); + write_constrain(out, cons); + fprintf(out, ")\n"); + break; + } + case CIL_VALIDATETRANS: { + struct cil_validatetrans *vt = node->data; + fprintf(out, "(validatetrans "); + fprintf(out, "%s ", datum_or_str(DATUM(vt->class), vt->class_str)); + if (vt->datum_expr) + write_expr(out, vt->datum_expr); + else + write_expr(out, vt->str_expr); + fprintf(out, ")\n"); + break; + } + case CIL_MLSVALIDATETRANS: { + struct cil_validatetrans *vt = node->data; + fprintf(out, "(mlsvalidatetrans "); + fprintf(out, "%s ", datum_or_str(DATUM(vt->class), vt->class_str)); + if (vt->datum_expr) + write_expr(out, vt->datum_expr); + else + write_expr(out, vt->str_expr); + fprintf(out, ")\n"); + break; + } + case CIL_CONTEXT: { + struct cil_context *context = node->data; + fprintf(out, "(context %s ", datum_to_str(DATUM(context))); + write_context(out, context, CIL_FALSE); + fprintf(out, ")\n"); + break; + } + case CIL_FILECON: { + struct cil_filecon *filecon = node->data; + fprintf(out, "(filecon "); + fprintf(out, "\"%s\" ", filecon->path_str); + switch (filecon->type) { + case CIL_FILECON_ANY: + fprintf(out, "%s ", CIL_KEY_ANY); + break; + case CIL_FILECON_FILE: + fprintf(out, "%s ", CIL_KEY_FILE); + break; + case CIL_FILECON_DIR: + fprintf(out, "%s ", CIL_KEY_DIR); + break; + case CIL_FILECON_CHAR: + fprintf(out, "%s ", CIL_KEY_CHAR); + break; + case CIL_FILECON_BLOCK: + fprintf(out, "%s ", CIL_KEY_BLOCK); + break; + case CIL_FILECON_SOCKET: + fprintf(out, "%s ", CIL_KEY_SOCKET); + break; + case CIL_FILECON_PIPE: + fprintf(out, "%s ", CIL_KEY_PIPE); + break; + case CIL_FILECON_SYMLINK: + fprintf(out, "%s ", CIL_KEY_SYMLINK); + break; + default: + fprintf(out, " "); + } + if (filecon->context) + write_context(out, filecon->context, CIL_TRUE); + else if (filecon->context_str) + fprintf(out, "%s", filecon->context_str); + else + fprintf(out, "()"); + fprintf(out, ")\n"); + break; + } + case CIL_IBPKEYCON: { + struct cil_ibpkeycon *ibpkeycon = node->data; + fprintf(out, "(ibpkeycon %s ", ibpkeycon->subnet_prefix_str); + fprintf(out, "(%d %d) ", ibpkeycon->pkey_low, ibpkeycon->pkey_high); + if (ibpkeycon->context) + write_context(out, ibpkeycon->context, CIL_TRUE); + else if (ibpkeycon->context_str) + fprintf(out, "%s", ibpkeycon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_PORTCON: { + struct cil_portcon *portcon = node->data; + fprintf(out, "(portcon "); + if (portcon->proto == CIL_PROTOCOL_UDP) + fprintf(out, " udp "); + else if (portcon->proto == CIL_PROTOCOL_TCP) + fprintf(out, " tcp "); + else if (portcon->proto == CIL_PROTOCOL_DCCP) + fprintf(out, "dccp "); + else if (portcon->proto == CIL_PROTOCOL_SCTP) + fprintf(out, "sctp "); + else + fprintf(out, " "); + if (portcon->port_low == portcon->port_high) + fprintf(out, "%d ", portcon->port_low); + else + fprintf(out, "(%d %d) ", portcon->port_low, portcon->port_high); + if (portcon->context) + write_context(out, portcon->context, CIL_TRUE); + else + fprintf(out, "%s", portcon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_NODECON: { + struct cil_nodecon *nodecon = node->data; + fprintf(out, "(nodecon "); + if (nodecon->addr) + write_ipaddr(out, nodecon->addr); + else + fprintf(out, "%s ", nodecon->addr_str); + fprintf(out, " "); + if (nodecon->mask) + write_ipaddr(out, nodecon->mask); + else + fprintf(out, "%s ", nodecon->mask_str); + fprintf(out, " "); + if (nodecon->context) + write_context(out, nodecon->context, CIL_TRUE); + else + fprintf(out, "%s", nodecon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_GENFSCON: { + struct cil_genfscon *genfscon = node->data; + fprintf(out, "(genfscon "); + fprintf(out, "%s \"%s\" ", genfscon->fs_str, genfscon->path_str); + if (genfscon->file_type != CIL_FILECON_ANY) { + switch (genfscon->file_type) { + case CIL_FILECON_FILE: + fprintf(out, "%s ", CIL_KEY_FILE); + break; + case CIL_FILECON_DIR: + fprintf(out, "%s ", CIL_KEY_DIR); + break; + case CIL_FILECON_CHAR: + fprintf(out, "%s ", CIL_KEY_CHAR); + break; + case CIL_FILECON_BLOCK: + fprintf(out, "%s ", CIL_KEY_BLOCK); + break; + case CIL_FILECON_SOCKET: + fprintf(out, "%s ", CIL_KEY_SOCKET); + break; + case CIL_FILECON_PIPE: + fprintf(out, "%s ", CIL_KEY_PIPE); + break; + case CIL_FILECON_SYMLINK: + fprintf(out, "%s ", CIL_KEY_SYMLINK); + break; + default: + fprintf(out, " "); + } + } + if (genfscon->context) + write_context(out, genfscon->context, CIL_TRUE); + else + fprintf(out, "%s", genfscon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_NETIFCON: { + struct cil_netifcon *netifcon = node->data; + fprintf(out, "(netifcon %s ", netifcon->interface_str); + if (netifcon->if_context) + write_context(out, netifcon->if_context, CIL_TRUE); + else + fprintf(out, "%s", netifcon->if_context_str); + fprintf(out, " "); + if (netifcon->packet_context) + write_context(out, netifcon->packet_context, CIL_TRUE); + else + fprintf(out, "%s", netifcon->packet_context_str); + fprintf(out, ")\n"); + break; + } + case CIL_IBENDPORTCON: { + struct cil_ibendportcon *ibendportcon = node->data; + fprintf(out, "(ibendportcon %s %u ", ibendportcon->dev_name_str, ibendportcon->port); + if (ibendportcon->context) + write_context(out, ibendportcon->context, CIL_TRUE); + else + fprintf(out, "%s", ibendportcon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_PIRQCON: { + struct cil_pirqcon *pirqcon = node->data; + fprintf(out, "(pirqcon %d ", pirqcon->pirq); + if (pirqcon->context) + write_context(out, pirqcon->context, CIL_TRUE); + else + fprintf(out, "%s", pirqcon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_IOMEMCON: { + struct cil_iomemcon *iomemcon = node->data; + fprintf(out, "(iomemcon (%"PRId64" %"PRId64") ", iomemcon->iomem_low, iomemcon->iomem_high); + if (iomemcon->context) + write_context(out, iomemcon->context, CIL_TRUE); + else + fprintf(out, "%s", iomemcon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_IOPORTCON: { + struct cil_ioportcon *ioportcon = node->data; + fprintf(out, "(ioportcon "); + if (ioportcon->ioport_low == ioportcon->ioport_high) + fprintf(out, "%d ", ioportcon->ioport_low); + else + fprintf(out, "(%d %d) ", ioportcon->ioport_low, ioportcon->ioport_high); + + if (ioportcon->context) + write_context(out, ioportcon->context, CIL_TRUE); + else + fprintf(out, "%s", ioportcon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_PCIDEVICECON: { + struct cil_pcidevicecon *pcidevicecon = node->data; + fprintf(out, "(pcidevicecon %d ", pcidevicecon->dev); + if (pcidevicecon->context) + write_context(out, pcidevicecon->context, CIL_TRUE); + else + fprintf(out, "%s", pcidevicecon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_DEVICETREECON: { + struct cil_devicetreecon *devicetreecon = node->data; + fprintf(out, "(devicetreecon \"%s\" ", devicetreecon->path); + if (devicetreecon->context) + write_context(out, devicetreecon->context, CIL_TRUE); + else + fprintf(out, "%s", devicetreecon->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_FSUSE: { + struct cil_fsuse *fsuse = node->data; + fprintf(out, "(fsuse "); + if (fsuse->type == CIL_FSUSE_XATTR) + fprintf(out, "xattr "); + else if (fsuse->type == CIL_FSUSE_TASK) + fprintf(out, "task "); + else if (fsuse->type == CIL_FSUSE_TRANS) + fprintf(out, "trans "); + else + fprintf(out, " "); + fprintf(out, "%s ", fsuse->fs_str); + if (fsuse->context) + write_context(out, fsuse->context, CIL_TRUE); + else + fprintf(out, "%s", fsuse->context_str); + fprintf(out, ")\n"); + break; + } + case CIL_POLICYCAP: { + struct cil_policycap *polcap = node->data; + fprintf(out, "(policycap %s)\n", polcap->datum.name); + break; + } + case CIL_IPADDR: { + struct cil_ipaddr *ipaddr = node->data; + char buf[256]; + if (inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256) == NULL) + strcpy(buf, ""); + fprintf(out, "(ipaddr %s %s)\n", datum_to_str(&ipaddr->datum), buf); + break; + } + default : + fprintf(out, "()\n", cil_node_to_string(node)); + break; + } +} + +/* + * Tree walk data and helper functions for writing the AST of the various phases + */ + +struct cil_write_ast_args { + FILE *out; + int depth; +}; + +/* + * Helper functions for writing the parse AST + */ + +static int __write_parse_ast_node_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) +{ + struct cil_write_ast_args *args = extra_args; + + fprintf(args->out, "%*s", args->depth*4, ""); + if (!node->data) { + if (node->cl_head) + fprintf(args->out, "(\n"); + else + fprintf(args->out, "()\n"); + } else { + char *str = (char *)node->data; + size_t len = strlen(str); + size_t i; + + for (i = 0; i < len; i++) { + if (isspace(str[i])) { + fprintf(args->out, "\"%s\"\n", str); + return SEPOL_OK; + } + } + + fprintf(args->out, "%s\n", (char *)node->data); + } + + return SEPOL_OK; +} + +static int __write_parse_ast_first_child_helper(struct cil_tree_node *node, void *extra_args) +{ + struct cil_write_ast_args *args = extra_args; + struct cil_tree_node *parent = node->parent; + + if (parent->flavor != CIL_ROOT) { + args->depth++; + } + + return SEPOL_OK; +} + +static int __write_parse_ast_last_child_helper(struct cil_tree_node *node, void *extra_args) +{ + struct cil_write_ast_args *args = extra_args; + struct cil_tree_node *parent = node->parent; + + if (parent->flavor == CIL_ROOT) { + return SEPOL_OK; + } + + args->depth--; + fprintf(args->out, "%*s", args->depth*4, ""); + fprintf(args->out, ")\n"); + + return SEPOL_OK; +} + +/* + * Helper functions for writing the CIL AST for the build and resolve phases + */ + +static int __write_cil_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + struct cil_write_ast_args *args = extra_args; + + if (node->flavor == CIL_SRC_INFO) { + cil_write_src_info_node(args->out, node); + return SEPOL_OK; + } + + fprintf(args->out, "%*s", args->depth*4, ""); + + cil_write_ast_node(args->out, node); + + if (node->flavor == CIL_CLASS || node->flavor == CIL_COMMON || node->flavor == CIL_MAP_CLASS) { + *finished = CIL_TREE_SKIP_HEAD; + } + + return SEPOL_OK; +} + +static int __write_cil_ast_first_child_helper(struct cil_tree_node *node, void *extra_args) +{ + struct cil_write_ast_args *args = extra_args; + struct cil_tree_node *parent = node->parent; + + if (parent->flavor != CIL_SRC_INFO && parent->flavor != CIL_ROOT) { + args->depth++; + } + + return SEPOL_OK; +} + +static int __write_cil_ast_last_child_helper(struct cil_tree_node *node, void *extra_args) +{ + struct cil_write_ast_args *args = extra_args; + struct cil_tree_node *parent = node->parent; + + if (parent->flavor == CIL_ROOT) { + return SEPOL_OK; + } else if (parent->flavor == CIL_SRC_INFO) { + fprintf(args->out, ";;* lme\n"); + return SEPOL_OK; + } + + args->depth--; + fprintf(args->out, "%*s", args->depth*4, ""); + fprintf(args->out, ")\n"); + + return SEPOL_OK; +} + +int cil_write_ast(FILE *out, enum cil_write_ast_phase phase, struct cil_tree_node *node) +{ + struct cil_write_ast_args extra_args; + int rc; + + extra_args.out = out; + extra_args.depth = 0; + + if (phase == CIL_WRITE_AST_PHASE_PARSE) { + rc = cil_tree_walk(node, __write_parse_ast_node_helper, __write_parse_ast_first_child_helper, __write_parse_ast_last_child_helper, &extra_args); + } else { + rc = cil_tree_walk(node, __write_cil_ast_node_helper, __write_cil_ast_first_child_helper, __write_cil_ast_last_child_helper, &extra_args); + } + + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to write AST\n"); + return SEPOL_ERR; + } + + return SEPOL_OK; +} diff --git a/kernel/libsepol/cil/src/cil_write_ast.h b/kernel/libsepol/cil/src/cil_write_ast.h new file mode 100644 index 00000000..3f4b9d95 --- /dev/null +++ b/kernel/libsepol/cil/src/cil_write_ast.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CIL_WRITE_AST_H_ +#define CIL_WRITE_AST_H_ + +#include + +#include "cil_tree.h" + +enum cil_write_ast_phase { + CIL_WRITE_AST_PHASE_PARSE = 0, + CIL_WRITE_AST_PHASE_BUILD, + CIL_WRITE_AST_PHASE_RESOLVE, +}; + +void cil_write_ast_node(FILE *out, struct cil_tree_node *node); +int cil_write_ast(FILE *out, enum cil_write_ast_phase phase, struct cil_tree_node *node); + +#endif /* CIL_WRITE_AST_H_ */ diff --git a/kernel/libsepol/cil/test/integration_testing/mls_policy.cil b/kernel/libsepol/cil/test/integration_testing/mls_policy.cil new file mode 100644 index 00000000..535ac110 --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/mls_policy.cil @@ -0,0 +1,115 @@ +(class testing (read open close write exec)) +(class fooclass (read open close write exec)) + +(category c0) +(category c1) +(category c2) +(category c3) +(category c4) +(categoryalias c0 cat) +(categoryorder (c0 c1 c2 c3 c4)) +(categoryset catset (c0 c2 c3)) +(sensitivity s0) +(sensitivity s1) +(sensitivity s2) +(sensitivity s3) +(sensitivityalias s3 sens) +(dominance (s0 s1 s2 s3)) +(sensitivitycategory s0 (c0 c2 c3)) +(sensitivitycategory s0 (cat)) +; the following causes a segfault +;(sensitivitycategory sens (c2)) +(type foo_t) +(type typea_t) +(type typeb_t) +(type typec_t) +(role foo_r) +(role rolea_r) +(role roleb_r) +(user foo_u) +(user user_u) +(userrole foo_u foo_r) +(level low (s0 catset)) +(level high (s0 (c0))) +(level test_l (s0 (cat))) + +(sid test_sid) +(sidcontext test_sid (foo_u foo_r foo_t (s0 (c0)) (s0 (c0)))) +(sid test_sid_anon_l) +(sidcontext test_sid_anon_l (foo_u foo_r foo_t low high)) + +(context con (foo_u foo_r foo_t low high)) +(context con_anon_l (foo_u foo_r foo_t (s0 (c0)) high)) +(fsuse xattr ext3 con) +(fsuse xattr ext3 con_anon_l) + +(netifcon eth0 con con_anon_l) + +(ipaddr ip_v4 192.25.35.200) +(ipaddr netmask 192.168.1.1) +(ipaddr ip_v6 2001:0DB8:AC10:FE01::) +(ipaddr netmask_v6 2001:0DE0:DA88:2222::) +; will need anon levels +(nodecon ip_v4 netmask con) +(nodecon ip_v6 netmask_v6 con_anon_l) + +;needs anon levels +(portcon type 25 con) + +(filecon root path file con) + +(genfscon type path con) + +(netifcon eth0 con con_anon_l) + +(typemember typea_t typeb_t testing typec_t) +(typechange typea_t typeb_t testing typec_t) +(typetransition typea_t typeb_t testing typec_t) + +(permissionset permset (open close)) +(allow typea_t typeb_t testing (write)) +(allow typea_t typeb_t testing permset) + +(roleallow rolea_r roleb_r) + +(rolebounds rolea_r roleb_r) + +(roletransition foo_r foo_t testing rolea_r) + +(level l2 (s0 (c0))) +(level h2 (s0 (c0))) +(mlsconstrain (fooclass testing)(open close)(eq l2 h2)) + +(common fooclass (open)) +(classcommon fooclass fooclass) + +(rangetransition typea_t typeb_t fooclass low high) + +(nametypetransition string typea_t typeb_t fooclass foo_t) + +(typepermissive foo_t) + +(typebounds typea_t typeb_t) + +(block test_b + (typealias .test_b.test typea_t) + (type test)) + +(attribute attrs) +(attributetypes attrs (foo_t)) + +(roletype foo_r foo_t) + +(userbounds user_u foo_u) + +(userrole user_u foo_r) + +(bool foo_b true) +(bool baz_b false) +(booleanif (&& foo_b baz_b) + (allow typea_t typeb_t fooclass(read))) +;(class baz (read)) +;(booleanif (&& foo_b baz_b) +; (allow foo_b baz_b fooclass (read))) + + diff --git a/kernel/libsepol/cil/test/integration_testing/nonmls.cil b/kernel/libsepol/cil/test/integration_testing/nonmls.cil new file mode 100644 index 00000000..382b95db --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/nonmls.cil @@ -0,0 +1,86 @@ +(class testing (read open close write exec)) +(class fooclass (read open close write exec)) + +(type foo_t) +(type typea_t) +(type typeb_t) +(type typec_t) +(role foo_r) +(role rolea_r) +(role roleb_r) +(user foo_u) +(user user_u) +(userrole foo_u foo_r) + +(sid test_sid) +;(sidcontext test_sid (foo_u foo_r foo_t (s0 (c0)) (s0 (c0)))) +;(sid test_sid_anon_l) + +;(fsuse xattr ext3 con) +;(fsuse xattr ext3 con_anon_l) + +;(netifcon eth0 con con_anon_l) + +(ipaddr ip_v4 192.25.35.200) +(ipaddr netmask 192.168.1.1) +(ipaddr ip_v6 2001:0DB8:AC10:FE01::) +(ipaddr netmask_v6 2001:0DE0:DA88:2222::) +; will need anon levels +;(nodecon ip_v4 netmask con) +;(nodecon ip_v6 netmask_v6 con_anon_l) + +;needs anon levels +;(portcon type 25 con) + +;(filecon root path file con) + +;(genfscon type path con) + +;(netifcon eth0 con con_anon_l) + +(typemember typea_t typeb_t testing typec_t) +(typechange typea_t typeb_t testing typec_t) +(typetransition typea_t typeb_t testing typec_t) + +(permissionset permset (open close)) +(allow typea_t typeb_t testing (write)) +(allow typea_t typeb_t testing permset) + +(roleallow rolea_r roleb_r) + +(rolebounds rolea_r roleb_r) + +(roletransition foo_r foo_t testing rolea_r) + +(common fooclass (open)) +(classcommon fooclass fooclass) + + +(nametypetransition string typea_t typeb_t fooclass foo_t) + +(typepermissive foo_t) + +(typebounds typea_t typeb_t) + +(block test_b + (typealias .test_b.test typea_t) + (type test)) + +(attribute attrs) +(attributetypes attrs (foo_t)) + +(roletype foo_r foo_t) + +(userbounds user_u foo_u) + +(userrole user_u foo_r) + +;(bool foo_b true) +;(bool baz_b false) +;(booleanif (&& foo_b baz_b) +; (allow typea_t typeb_t fooclass(read))) +;(class baz (read)) +;(booleanif (&& foo_b baz_b) +; (allow foo_b baz_b fooclass (read))) + + diff --git a/kernel/libsepol/cil/test/integration_testing/nonmls.conf b/kernel/libsepol/cil/test/integration_testing/nonmls.conf new file mode 100644 index 00000000..729c7b1a --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/nonmls.conf @@ -0,0 +1,76 @@ + +class testing +class fooclass + +sid test_sid +#end + +#sid decl +sid security + + +class testing +{ + read + open + close + write + exec +} +class fooclass +{ + read + open + close + write + exec +} +#end + +#attribs + +attribute attrs; +#end + + +type foo_t, attrs; +type typea_t; +type typeb_t; +type typec_t; +#end + + +bool foo_b true; +bool baz_b false; +#end + + +role foo_r types foo_t; +role rolea_r; +role roleb_r; +#end + +#role decl + + +allow typea_t typeb_t : testing write; +allow typea_t typeb_t : testing {open close}; +type_transition typea_t typeb_t : testing typec_t; +#end + +#audit rules +#dontaudit {kernel} unknown : dir search; + + +allow rolea_r roleb_r; +#end + +#rbac stuff +#allow system {guest local_user}; +#allow local_user guest; + + +user foo_u roles foo_r; +#end + +sid test_sid foo_u:foo_r:foo_t diff --git a/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad1.cil b/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad1.cil new file mode 100644 index 00000000..321fe2f6 --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad1.cil @@ -0,0 +1,42 @@ +; Minimum policy +; **************************** + +(class foo (read)) + +(type bar) +(allow bar self (foo (read))) + +; **************************** + +(sensitivity s0) +(sensitivity s1) +(sensitivity s2) +(sensitivity s3) +(sensitivity s4) +(sensitivity s5) +(sensitivity s6) +(sensitivity s7) +(sensitivity s8) +(sensitivity s9) +(dominance (s2 s3 s4)) +(dominance (s1 s2 s4 s5)) +(dominance (s5 s6 s8)) +(dominance (s6 s7 s8 s9)) + +(category c0) +(category c1) +(category c2) +(category c3) +(category c4) +(category c5) +(category c6) +(category c7) +(category c8) +(category c9) + +(categoryorder (c1 c3)) +(categoryorder (c1 c2 c3)) +(categoryorder (c5 c6 c7)) +(categoryorder (c3 c4 c5)) +(categoryorder (c7 c8 c9)) +(categoryorder (c0 c1)) diff --git a/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad2.cil b/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad2.cil new file mode 100644 index 00000000..9e84191a --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad2.cil @@ -0,0 +1,43 @@ +; Minimum policy +; **************************** + +(class foo (read)) + +(type bar) +(allow bar self (foo (read))) + +; **************************** + +(sensitivity s0) +(sensitivity s1) +(sensitivity s2) +(sensitivity s3) +(sensitivity s4) +(sensitivity s5) +(sensitivity s6) +(sensitivity s7) +(sensitivity s8) +(sensitivity s9) +(dominance (s2 s3 s4)) +(dominance (s1 s2 s4 s5)) +(dominance (s5 s6 s8)) +(dominance (s6 s7 s8 s9)) +(dominance (s0 s1)) + +(category c0) +(category c1) +(category c2) +(category c3) +(category c4) +(category c5) +(category c6) +(category c7) +(category c8) +(category c9) + +(categoryorder (c1 c3)) +(categoryorder (c1 c2 c3)) +(categoryorder (c5 c6 c7)) +(categoryorder (c3 c4 c5)) +(categoryorder (c7 c8 c9)) + diff --git a/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad3.cil b/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad3.cil new file mode 100644 index 00000000..36aa6878 --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/ordered_lists_bad3.cil @@ -0,0 +1,43 @@ +; Minimum policy +; **************************** + +(class foo (read)) + +(type bar) +(allow bar self (foo (read))) + +; **************************** + +(sensitivity s0) +(sensitivity s1) +(sensitivity s2) +(sensitivity s3) +(sensitivity s4) +(sensitivity s5) +(sensitivity s6) +(sensitivity s7) +(sensitivity s8) +(sensitivity s9) +(dominance (s2 s3 s4)) +(dominance (s1 s2 s5)) +(dominance (s5 s6 s8)) +(dominance (s6 s7 s8 s9)) +(dominance (s0 s1)) + +(category c0) +(category c1) +(category c2) +(category c3) +(category c4) +(category c5) +(category c6) +(category c7) +(category c8) +(category c9) + +(categoryorder (c1 c3)) +(categoryorder (c1 c2 c3)) +(categoryorder (c5 c6 c7)) +(categoryorder (c3 c4 c5)) +(categoryorder (c7 c8 c9)) +(categoryorder (c0 c1)) diff --git a/kernel/libsepol/cil/test/integration_testing/ordered_lists_easy.cil b/kernel/libsepol/cil/test/integration_testing/ordered_lists_easy.cil new file mode 100644 index 00000000..36df1e6a --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/ordered_lists_easy.cil @@ -0,0 +1,38 @@ +; Minimum policy +; **************************** + +(class foo (read)) + +(type bar) +(allow bar self (foo (read))) + +; **************************** + +(sensitivity s0) +(sensitivity s1) +(sensitivity s2) +(sensitivity s3) +(sensitivity s4) +(sensitivity s5) +(sensitivity s6) +(sensitivity s7) +(sensitivity s8) +(sensitivity s9) +(dominance (s0 s1 s2 s3 s4 s5 s6 s7 s8 s9)) + +(category c0) +(category c1) +(category c2) +(category c3) +(category c4) +(category c5) +(category c6) +(category c7) +(category c8) +(category c9) + +(categoryorder (c2 c3 c4 c5)) +(categoryorder (c0 c1 c2 c3)) +(categoryorder (c5 c6 c7)) +(categoryorder (c7 c8 c9)) + diff --git a/kernel/libsepol/cil/test/integration_testing/ordered_lists_hard.cil b/kernel/libsepol/cil/test/integration_testing/ordered_lists_hard.cil new file mode 100644 index 00000000..f00c5b1b --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/ordered_lists_hard.cil @@ -0,0 +1,43 @@ +; Minimum policy +; **************************** + +(class foo (read)) + +(type bar) +(allow bar self (foo (read))) + +; **************************** + +(sensitivity s0) +(sensitivity s1) +(sensitivity s2) +(sensitivity s3) +(sensitivity s4) +(sensitivity s5) +(sensitivity s6) +(sensitivity s7) +(sensitivity s8) +(sensitivity s9) +(dominance (s2 s3 s4)) +(dominance (s1 s2 s4 s5)) +(dominance (s5 s6 s8)) +(dominance (s6 s7 s8 s9)) +(dominance (s0 s1)) + +(category c0) +(category c1) +(category c2) +(category c3) +(category c4) +(category c5) +(category c6) +(category c7) +(category c8) +(category c9) + +(categoryorder (c1 c3)) +(categoryorder (c1 c2 c3)) +(categoryorder (c5 c6 c7)) +(categoryorder (c3 c4 c5)) +(categoryorder (c7 c8 c9)) +(categoryorder (c0 c1)) diff --git a/kernel/libsepol/cil/test/integration_testing/small.cil b/kernel/libsepol/cil/test/integration_testing/small.cil new file mode 100644 index 00000000..99731667 --- /dev/null +++ b/kernel/libsepol/cil/test/integration_testing/small.cil @@ -0,0 +1,5 @@ +(class foo (read)) + +(type bar) +(allow bar self (foo (read))) + diff --git a/kernel/libsepol/cil/test/unit/AllTests.c b/kernel/libsepol/cil/test/unit/AllTests.c new file mode 100644 index 00000000..40080c8a --- /dev/null +++ b/kernel/libsepol/cil/test/unit/AllTests.c @@ -0,0 +1,76 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include "CuTest.h" +#include "../../src/cil_log.h" + +CuSuite* CilTreeGetSuite(void); +CuSuite* CilTreeGetResolveSuite(void); +CuSuite* CilTreeGetBuildSuite(void); +CuSuite* CilTestFullCil(void); + +void RunAllTests(void) { + /* disable cil log output */ + cil_set_log_level(0); + + CuString *output = CuStringNew(); + CuSuite* suite = CuSuiteNew(); + CuSuite* suiteResolve = CuSuiteNew(); + CuSuite* suiteBuild = CuSuiteNew(); + CuSuite* suiteIntegration = CuSuiteNew(); + + CuSuiteAddSuite(suite, CilTreeGetSuite()); + CuSuiteAddSuite(suiteResolve, CilTreeGetResolveSuite()); + CuSuiteAddSuite(suiteBuild, CilTreeGetBuildSuite()); + CuSuiteAddSuite(suiteIntegration, CilTestFullCil()); + + CuSuiteRun(suite); + CuSuiteDetails(suite, output); + CuSuiteSummary(suite, output); + + CuSuiteRun(suiteResolve); + CuSuiteDetails(suiteResolve, output); + CuSuiteSummary(suiteResolve, output); + + CuSuiteRun(suiteBuild); + CuSuiteDetails(suiteBuild, output); + CuSuiteSummary(suiteBuild, output); + + CuSuiteRun(suiteIntegration); + CuSuiteDetails(suiteIntegration, output); + CuSuiteSummary(suiteIntegration, output); + printf("\n%s\n", output->buffer); +} + +int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) { + RunAllTests(); + + return 0; +} diff --git a/kernel/libsepol/cil/test/unit/CilTest.c b/kernel/libsepol/cil/test/unit/CilTest.c new file mode 100644 index 00000000..00d709a8 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/CilTest.c @@ -0,0 +1,1974 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include +#include +#include +#include +#include +#include + +#include "CuTest.h" +#include "CilTest.h" + +#include "../../src/cil_internal.h" + +#include "test_cil.h" +#include "test_cil_tree.h" +#include "test_cil_list.h" +#include "test_cil_symtab.h" +#include "test_cil_parser.h" +#include "test_cil_lexer.h" +#include "test_cil_build_ast.h" +#include "test_cil_resolve_ast.h" +#include "test_cil_fqn.h" +#include "test_cil_copy_ast.h" +#include "test_cil_post.h" +#include "test_integration.h" + +void set_cil_file_data(struct cil_file_data **data) { + struct cil_file_data *new_data = malloc(sizeof(*new_data)); + FILE *file; + struct stat filedata; + uint32_t file_size; + char *buffer; + + file = fopen("test/policy.cil", "r"); + if (!file) { + fprintf(stderr, "Could not open file\n"); + exit(1); + } + if (stat("test/policy.cil", &filedata) == -1) { + printf("Could not stat file\n"); + exit(1); + } + file_size = filedata.st_size; + + buffer = malloc(file_size + 2); + if(fread(buffer, file_size, 1, file) < 1) { + exit(1); + } + memset(buffer+file_size, 0, 2); + fclose(file); + + + new_data->buffer = buffer; + new_data->file_size = file_size; + + *data = new_data; + +} + +void gen_test_tree(struct cil_tree **test_root, char *line[]) { + struct cil_tree *new_tree = malloc(sizeof(*new_tree)); + struct cil_tree_node *node, *item, *current; + + cil_tree_init(&new_tree); + new_tree->root->flavor = CIL_ROOT; + current = new_tree->root; + + char **i = line; + do { + if (*i[0] == '(') { + cil_tree_node_init(&node); + node->parent = current; + node->flavor = CIL_PARSE_NODE; + node->line = 0; + if (current->cl_head == NULL) + current->cl_head = node; + else + current->cl_tail->next = node; + current->cl_tail = node; + current = node; + } + else if (*i[0] == ')') + current = current->parent; + else { + cil_tree_node_init(&item); + item->parent = current; + item->data = cil_strdup(*i); + item->flavor = CIL_PARSE_NODE; + item->line = 0; + if (current->cl_head == NULL) { + current->cl_head = item; + } + else { + current->cl_tail->next = item; + } + current->cl_tail = item; + } + i++; + } while(*i != NULL); + + *test_root = new_tree; +} + +void test_symtab_init(CuTest *tc) { + struct cil_db *test_new_db; + test_new_db = malloc(sizeof(*test_new_db)); + + uint32_t rc = 0, i =0; + + for (i = 0; i < CIL_SYM_NUM; i++) { + rc = ksu_symtab_init(&test_new_db->symtab[i], cil_sym_sizes[CIL_SYM_ARRAY_ROOT][i]); + CuAssertIntEquals(tc, 0, rc); + // TODO CDS add checks to make sure the symtab looks correct + } + + free(test_new_db); +} + +void test_symtab_init_no_table_neg(CuTest *tc) { + struct cil_db *test_new_db; + test_new_db = malloc(sizeof(*test_new_db)); + + int rc = ksu_symtab_init(&test_new_db->symtab[0], (uint32_t)SIZE_MAX); + CuAssertIntEquals(tc, -1, rc); + + free(test_new_db); +} + +CuSuite* CilTreeGetResolveSuite(void) { + CuSuite* suite = CuSuiteNew(); + + /* test_cil_resolve_ast.c */ + SUITE_ADD_TEST(suite, test_cil_resolve_ast_curr_null_neg); + SUITE_ADD_TEST(suite, test_cil_gen_perm_nodes_inval_perm_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_name); + SUITE_ADD_TEST(suite, test_cil_resolve_name_invalid_type_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_type_in_multiple_attrs); + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_multiple_excludes_with_not); + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_multiple_types_with_and); + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_using_attr); + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_name_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_undef_type_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_not); + SUITE_ADD_TEST(suite, test_cil_resolve_typeattributeset_undef_type_not_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typeattributeset); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typeattributeset_undef_type_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_typealias); + SUITE_ADD_TEST(suite, test_cil_resolve_typealias_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typealias); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typealias_notype_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_typebounds); + SUITE_ADD_TEST(suite, test_cil_resolve_typebounds_repeatbind_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_typebounds_type1_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_typebounds_type2_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typebounds); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typebounds_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_typepermissive); + SUITE_ADD_TEST(suite, test_cil_resolve_typepermissive_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typepermissive); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_typepermissive_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_nametypetransition); + SUITE_ADD_TEST(suite, test_cil_resolve_nametypetransition_src_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_nametypetransition_tgt_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_nametypetransition_class_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_nametypetransition_dest_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_nametypetransition); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_nametypetransition_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_namedrange); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_namedrange_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_namedrange_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_namedrange_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_type1_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_type2_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_class_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_call_level_l_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_call_level_l_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_call_level_h_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_call_level_h_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_level_l_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_level_h_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_anon_level_l); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_anon_level_l_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_anon_level_h); + SUITE_ADD_TEST(suite, test_cil_resolve_rangetransition_anon_level_h_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_rangetransition); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_rangetransition_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_classcommon); + SUITE_ADD_TEST(suite, test_cil_resolve_classcommon_no_class_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_classcommon_no_common_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_classcommon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_classcommon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_classmapping_named); + SUITE_ADD_TEST(suite, test_cil_resolve_classmapping_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_classmapping_anon_inmacro); + SUITE_ADD_TEST(suite, test_cil_resolve_classmapping_anon_inmacro_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_classmapping_named_classmapname_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_classmapping_anon_classmapname_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_classmapping_anon_permset_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_rolebounds); + SUITE_ADD_TEST(suite, test_cil_resolve_rolebounds_exists_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rolebounds_role1_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_rolebounds_role2_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_rolebounds); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_rolebounds_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_sensalias); + SUITE_ADD_TEST(suite, test_cil_resolve_sensalias_sensdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_sensalias); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_sensalias_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_catalias); + SUITE_ADD_TEST(suite, test_cil_resolve_catalias_catdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catalias); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catalias_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_catorder); + SUITE_ADD_TEST(suite, test_cil_resolve_catorder_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catorder); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catorder_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_dominance); + SUITE_ADD_TEST(suite, test_cil_resolve_dominance_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_dominance); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_dominance_neg); + //TODO: test for __cil_set_order + + SUITE_ADD_TEST(suite, test_cil_resolve_catset); + SUITE_ADD_TEST(suite, test_cil_resolve_catset_catlist_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catset); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catset_catlist_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_catrange); + SUITE_ADD_TEST(suite, test_cil_resolve_catrange_catloworder_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_catrange_cathighorder_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_catrange_cat1_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_catrange_cat2_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catrange); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_catrange_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_senscat); + SUITE_ADD_TEST(suite, test_cil_resolve_senscat_catrange_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_senscat_catsetname); + SUITE_ADD_TEST(suite, test_cil_resolve_senscat_catsetname_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_senscat_sublist); + SUITE_ADD_TEST(suite, test_cil_resolve_senscat_missingsens_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_senscat_category_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_senscat_currrangecat); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_senscat); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_senscat_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_level); + SUITE_ADD_TEST(suite, test_cil_resolve_level_catlist); + SUITE_ADD_TEST(suite, test_cil_resolve_level_catset); + SUITE_ADD_TEST(suite, test_cil_resolve_level_catset_name_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_level_sens_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_level_cat_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_level_senscat_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_level); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_level_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_levelrange_namedlvl); + SUITE_ADD_TEST(suite, test_cil_resolve_levelrange_namedlvl_low_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_levelrange_namedlvl_high_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_levelrange_anonlvl); + SUITE_ADD_TEST(suite, test_cil_resolve_levelrange_anonlvl_low_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_levelrange_anonlvl_high_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_levelrange); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_levelrange_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_constrain); + SUITE_ADD_TEST(suite, test_cil_resolve_constrain_class_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_constrain_perm_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_constrain_perm_resolve_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_constrain); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_constrain_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_mlsconstrain); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_mlsconstrain_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_context); + SUITE_ADD_TEST(suite, test_cil_resolve_context_macro); + SUITE_ADD_TEST(suite, test_cil_resolve_context_macro_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_context_namedrange); + SUITE_ADD_TEST(suite, test_cil_resolve_context_namedrange_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_context_user_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_context_role_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_context_type_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_context_anon_level_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_context); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_context_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_roletransition); + SUITE_ADD_TEST(suite, test_cil_resolve_roletransition_srcdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_roletransition_tgtdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_roletransition_resultdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roletransition); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roletransition_srcdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roletransition_tgtdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roletransition_resultdecl_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_roleallow); + SUITE_ADD_TEST(suite, test_cil_resolve_roleallow_srcdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_roleallow_tgtdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roleallow); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roleallow_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_classpermset_named); + SUITE_ADD_TEST(suite, test_cil_resolve_classpermset_named_namedpermlist); + SUITE_ADD_TEST(suite, test_cil_resolve_classpermset_named_permlist_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_classpermset_named_unnamedcps_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_classpermset_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_classpermset_anon_namedpermlist); + SUITE_ADD_TEST(suite, test_cil_resolve_classpermset_anon_permlist_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_avrule); + SUITE_ADD_TEST(suite, test_cil_resolve_avrule_permset); + SUITE_ADD_TEST(suite, test_cil_resolve_avrule_permset_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_avrule_permset_permdne_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_avrule_firsttype_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_avrule_secondtype_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_avrule_class_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_avrule_perm_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_avrule); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_avrule_src_nores_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_avrule_tgt_nores_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_avrule_class_nores_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_avrule_datum_null_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_transition); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_transition_srcdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_transition_tgtdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_transition_objdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_transition_resultdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_type_rule_transition); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_type_rule_transition_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_change); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_change_srcdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_change_tgtdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_change_objdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_change_resultdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_type_rule_change); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_type_rule_change_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_member); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_member_srcdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_member_tgtdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_member_objdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_type_rule_member_resultdecl_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_type_rule_member); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_type_rule_member_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_filecon); + SUITE_ADD_TEST(suite, test_cil_resolve_filecon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_filecon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_filecon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_filecon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_filecon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_portcon); + SUITE_ADD_TEST(suite, test_cil_resolve_portcon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_portcon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_portcon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_portcon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_portcon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_genfscon); + SUITE_ADD_TEST(suite, test_cil_resolve_genfscon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_genfscon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_genfscon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_genfscon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_genfscon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_ipv4); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_ipv6); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_anonipaddr_ipv4); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_anonnetmask_ipv4); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_anonipaddr_ipv6); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_anonnetmask_ipv6); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_diffipfam_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_ipaddr_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_netmask_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_nodecon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_nodecon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_nodecon_ipaddr_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_nodecon_netmask_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_netifcon); + SUITE_ADD_TEST(suite, test_cil_resolve_netifcon_otf_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_netifcon_interface_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_netifcon_unnamed); + SUITE_ADD_TEST(suite, test_cil_resolve_netifcon_unnamed_packet_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_netifcon_unnamed_otf_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_netifcon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_netifcon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_pirqcon); + SUITE_ADD_TEST(suite, test_cil_resolve_pirqcon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_pirqcon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_pirqcon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_pirqcon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_pirqcon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_iomemcon); + SUITE_ADD_TEST(suite, test_cil_resolve_iomemcon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_iomemcon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_iomemcon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_iomemcon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_iomemcon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_ioportcon); + SUITE_ADD_TEST(suite, test_cil_resolve_ioportcon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ioportcon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_ioportcon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_ioportcon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_ioportcon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_pcidevicecon); + SUITE_ADD_TEST(suite, test_cil_resolve_pcidevicecon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_pcidevicecon_anon_context); + SUITE_ADD_TEST(suite, test_cil_resolve_pcidevicecon_anon_context_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_pcidevicecon); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_pcidevicecon_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_fsuse); + SUITE_ADD_TEST(suite, test_cil_resolve_fsuse_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_fsuse_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_fsuse_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_fsuse); + //SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_fsuse_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_sidcontext); + SUITE_ADD_TEST(suite, test_cil_resolve_sidcontext_named_levels); + SUITE_ADD_TEST(suite, test_cil_resolve_sidcontext_named_context); + SUITE_ADD_TEST(suite, test_cil_resolve_sidcontext_named_context_wrongname_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_sidcontext_named_context_invaliduser_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_sidcontext); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_sidcontext_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_blockinherit); + SUITE_ADD_TEST(suite, test_cil_resolve_blockinherit_blockstrdne_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_blockinherit); + + SUITE_ADD_TEST(suite, test_cil_resolve_in_block); + SUITE_ADD_TEST(suite, test_cil_resolve_in_blockstrdne_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_in_macro); + SUITE_ADD_TEST(suite, test_cil_resolve_in_optional); + + //SUITE_ADD_TEST(suite, test_cil_resolve_call1_noparam); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_type); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_role); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_user); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_sens); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_cat); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_catset); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_catset_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_catset_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_class); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_classmap); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_permset); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_permset_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_classpermset_named); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_classpermset_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_classpermset_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_level); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_level_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_level_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_ipaddr); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_ipaddr_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_ipaddr_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_unknown_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_unknowncall_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_extraargs_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_copy_dup); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_missing_arg_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_paramsflavor_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_call1_unknownflavor_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_call1); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_call1_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_call2_type); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_role); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_user); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_sens); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_cat); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_catset); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_catset_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_permset); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_permset_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_classpermset_named); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_classpermset_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_class); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_classmap); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_level); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_level_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_ipaddr); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_ipaddr_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_call2_unknown_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_call2); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_call2_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_name_call_args); + SUITE_ADD_TEST(suite, test_cil_resolve_name_call_args_multipleparams); + SUITE_ADD_TEST(suite, test_cil_resolve_name_call_args_diffflavor); + SUITE_ADD_TEST(suite, test_cil_resolve_name_call_args_callnull_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_name_call_args_namenull_neg); + //SUITE_ADD_TEST(suite, test_cil_resolve_name_call_args_callargsnull_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_name_call_args_name_neg); + +// SUITE_ADD_TEST(suite, test_cil_resolve_expr_stack_bools); +// SUITE_ADD_TEST(suite, test_cil_resolve_expr_stack_tunables); +// SUITE_ADD_TEST(suite, test_cil_resolve_expr_stack_type); +// SUITE_ADD_TEST(suite, test_cil_resolve_expr_stack_role); +// SUITE_ADD_TEST(suite, test_cil_resolve_expr_stack_user); +// SUITE_ADD_TEST(suite, test_cil_resolve_expr_stack_neg); +// SUITE_ADD_TEST(suite, test_cil_resolve_expr_stack_emptystr_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_boolif); + SUITE_ADD_TEST(suite, test_cil_resolve_boolif_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_boolif); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_boolif_neg); + + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_and); + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_not); + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_or); + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_xor); + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_eq); + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_neq); + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_oper1); + SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_oper2); + //SUITE_ADD_TEST(suite, test_cil_evaluate_expr_stack_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_tunif_false); + SUITE_ADD_TEST(suite, test_cil_resolve_tunif_true); + SUITE_ADD_TEST(suite, test_cil_resolve_tunif_resolveexpr_neg); + //SUITE_ADD_TEST(suite, test_cil_resolve_tunif_evaluateexpr_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_tunif); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_tunif_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_userbounds); + SUITE_ADD_TEST(suite, test_cil_resolve_userbounds_exists_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userbounds_user1_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userbounds_user2_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userbounds); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userbounds_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_roletype); + SUITE_ADD_TEST(suite, test_cil_resolve_roletype_type_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_roletype_role_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roletype); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roletype_role_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_roletype_type_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_userrole); + SUITE_ADD_TEST(suite, test_cil_resolve_userrole_user_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userrole_role_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userrole); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userrole_user_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userrole_role_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_userlevel); + SUITE_ADD_TEST(suite, test_cil_resolve_userlevel_macro); + SUITE_ADD_TEST(suite, test_cil_resolve_userlevel_macro_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userlevel_level_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_userlevel_level_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userlevel_user_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userlevel_level_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userlevel); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userlevel_neg); + + SUITE_ADD_TEST(suite, test_cil_resolve_userrange); + SUITE_ADD_TEST(suite, test_cil_resolve_userrange_macro); + SUITE_ADD_TEST(suite, test_cil_resolve_userrange_macro_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userrange_range_anon); + SUITE_ADD_TEST(suite, test_cil_resolve_userrange_range_anon_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userrange_user_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_userrange_range_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userrange); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_userrange_neg); + + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_optional_enabled); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_optional_disabled); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_block); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_user); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_role); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_type); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_typealias); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_common); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_class); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_bool); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_sens); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_cat); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_catset); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_sid); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_macro); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_context); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_level); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_policycap); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_perm); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_catalias); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_sensalias); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_tunable); + SUITE_ADD_TEST(suite, test_cil_disable_children_helper_unknown); + + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_callstack); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_call); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_optional); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_macro); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_optstack); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_optstack_tunable_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_optstack_macro_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_nodenull_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_extraargsnull_neg); + SUITE_ADD_TEST(suite, test_cil_resolve_ast_node_helper_optfailedtoresolve); + + return suite; +} + +CuSuite* CilTreeGetBuildSuite(void) { + CuSuite* suite = CuSuiteNew(); + + /* test_cil_build_ast.c */ + SUITE_ADD_TEST(suite, test_cil_build_ast); + SUITE_ADD_TEST(suite, test_cil_build_ast_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_treenull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_suberr_neg); + + SUITE_ADD_TEST(suite, test_cil_parse_to_list); + SUITE_ADD_TEST(suite, test_cil_parse_to_list_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_parse_to_list_listnull_neg); + + SUITE_ADD_TEST(suite, test_cil_set_to_list); + SUITE_ADD_TEST(suite, test_cil_set_to_list_listnull_neg); + SUITE_ADD_TEST(suite, test_cil_set_to_list_tree_node_null_neg); + SUITE_ADD_TEST(suite, test_cil_set_to_list_cl_head_null_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_block); + SUITE_ADD_TEST(suite, test_cil_gen_block_justblock_neg); + SUITE_ADD_TEST(suite, test_cil_gen_block_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_block_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_block_treenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_block_nodenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_block_nodeparentnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_block); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_block_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_blockinherit); + SUITE_ADD_TEST(suite, test_cil_gen_blockinherit_namelist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_blockinherit_namenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_blockinherit_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_blockinherit_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_blockinherit_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_blockinherit_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_blockinherit); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_blockinherit_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_perm); + SUITE_ADD_TEST(suite, test_cil_gen_perm_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_perm_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_perm_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_perm_nodenull_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_permset); + SUITE_ADD_TEST(suite, test_cil_gen_permset_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_permset_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_permset_noperms_neg); + SUITE_ADD_TEST(suite, test_cil_gen_permset_emptyperms_neg); + SUITE_ADD_TEST(suite, test_cil_gen_permset_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_permset_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_permset_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_permset_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_permset); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_permset_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_perm_nodes); + SUITE_ADD_TEST(suite, test_cil_gen_perm_nodes_failgen_neg); + + SUITE_ADD_TEST(suite, test_cil_fill_permset); + SUITE_ADD_TEST(suite, test_cil_fill_permset_sublist_neg); + SUITE_ADD_TEST(suite, test_cil_fill_permset_startpermnull_neg); + SUITE_ADD_TEST(suite, test_cil_fill_permset_permsetnull_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_in); + SUITE_ADD_TEST(suite, test_cil_gen_in_blockstrnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_in_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_in_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_in_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_in_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_in); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_in_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_class); + SUITE_ADD_TEST(suite, test_cil_gen_class_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_nodenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_noclassname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_namesublist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_noperms); + SUITE_ADD_TEST(suite, test_cil_gen_class_permsnotinlist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_extrapermlist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_class_listinlist_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_class); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_class_neg); + + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_anonperms); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_anonperms_neg); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_namedperms); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_extra_neg); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_emptypermslist_neg); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_noperms_neg); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_noclass_neg); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_classnodenull_neg); + SUITE_ADD_TEST(suite, test_cil_fill_classpermset_cpsnull_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_classpermset); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_noclass_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_noperms_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_emptyperms_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classpermset_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_classpermset); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_classpermset_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_classmap_perm); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_perm_dupeperm_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_perm_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_perm_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_perm_astnull_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_classmap); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_emptyperms_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmap_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_classmap); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_classmap_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_anonpermset); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_anonpermset_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_namedpermset); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_noclassmapname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_noclassmapperm_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_nopermissionsets_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classmapping_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_classmapping); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_classmapping_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_common); + SUITE_ADD_TEST(suite, test_cil_gen_common_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_common_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_common_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_common_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_common_twoperms_neg); + SUITE_ADD_TEST(suite, test_cil_gen_common_permsublist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_common_noperms_neg); + + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_common); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_common_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_sid); + SUITE_ADD_TEST(suite, test_cil_gen_sid_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sid_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sid_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sid_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sid_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sid_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sid); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sid_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_namedcontext); +// SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_halfcontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_empty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_nocontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_dblname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_pcurrnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sidcontext_astnodenull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sidcontext); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sidcontext_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_type); + SUITE_ADD_TEST(suite, test_cil_gen_type_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_typeattribute); + SUITE_ADD_TEST(suite, test_cil_gen_typeattribute_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattribute_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattribute_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattribute_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typeattribute); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typeattribute_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_typebounds); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_notype1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_type1inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_notype2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_type2inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typebounds_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typebounds); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typebounds_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_typepermissive); + SUITE_ADD_TEST(suite, test_cil_gen_typepermissive_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typepermissive_typeinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typepermissive_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typepermissive_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typepermissive_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typepermissive_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typepermissive); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typepermissive_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_nostr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_strinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_nosrc_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_srcinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_notgt_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_tgtinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_noclass_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_classinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_nodest_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_destinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nametypetransition_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_nametypetransition); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_nametypetransition_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_namedtransition); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_anon_low_l); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_anon_low_l_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_anon_high_l); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_anon_high_l_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_nofirsttype_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_firsttype_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_nosecondtype_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_secondtype_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_noclass_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_class_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_nolevel_l_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_nolevel_h_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rangetransition_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_rangetransition); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_rangetransition_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_and); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_or); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_xor); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_not); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_not_noexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_not_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_eq); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_neq); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_nested); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_nested_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_nested_emptyargs_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_nested_missingoperator_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_arg1null_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_arg2null_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_extraarg_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_expr_stack_stacknull_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_boolif_multiplebools_true); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_multiplebools_false); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_multiplebools_unknowncond_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_true); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_false); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_unknowncond_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_nested); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_nested_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_extra_parens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_nocond); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_nocond_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_notruelist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_boolif_empty_cond_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_boolif); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_boolif_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_tunif_multiplebools_true); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_multiplebools_false); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_multiplebools_unknowncond_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_true); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_false); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_unknowncond_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_nocond); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_nested); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_nested_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_extra_parens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_nocond_neg); + SUITE_ADD_TEST(suite, test_cil_gen_tunif_notruelist_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_tunif); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_tunif_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_condblock_true); + SUITE_ADD_TEST(suite, test_cil_gen_condblock_false); + SUITE_ADD_TEST(suite, test_cil_gen_condblock_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_condblock_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_condblock_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_condblock_nocond_neg); + SUITE_ADD_TEST(suite, test_cil_gen_condblock_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_condblock_true); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_condblock_true_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_condblock_false); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_condblock_false_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_typealias); + SUITE_ADD_TEST(suite, test_cil_gen_typealias_incomplete_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typealias_incomplete_neg2); + SUITE_ADD_TEST(suite, test_cil_gen_typealias_extratype_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typealias); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typealias_notype_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typealias_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typealias_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typealias_astnull_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_and_two_types); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_not); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_exclude_attr); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_exclude_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_emptylists_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_listinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_typeattributeset_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typeattributeset); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_typeattributeset_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_userbounds); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_notype1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_type1_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_notype2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_type2_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userbounds_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userbounds); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userbounds_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_role); + SUITE_ADD_TEST(suite, test_cil_gen_role_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_role_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_role_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_role_extrarole_neg); + SUITE_ADD_TEST(suite, test_cil_gen_role_noname_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_role); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_role_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_roletransition); + SUITE_ADD_TEST(suite, test_cil_gen_roletransition_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletransition_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletransition_srcnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletransition_tgtnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletransition_resultnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletransition_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_roletransition); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_roletransition_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_bool_true); + SUITE_ADD_TEST(suite, test_cil_gen_bool_tunable_true); + SUITE_ADD_TEST(suite, test_cil_gen_bool_false); + SUITE_ADD_TEST(suite, test_cil_gen_bool_tunable_false); + SUITE_ADD_TEST(suite, test_cil_gen_bool_none_neg); + SUITE_ADD_TEST(suite, test_cil_gen_bool_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_bool_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_bool_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_bool_notbool_neg); + SUITE_ADD_TEST(suite, test_cil_gen_bool_boolname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_bool_extraname_false_neg); + SUITE_ADD_TEST(suite, test_cil_gen_bool_extraname_true_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_bool); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_bool_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_bool_tunable); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_bool_tunable_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_t1type); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_t1t1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_t2type); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_t2t2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_r1role); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_r1r1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_r2role); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_r2r2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_t1t2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_r1r2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_r1r2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_u1u2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_u1user); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_u1u1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_u2user); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_u2u2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_l2h2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_l2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_l1l2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_l1h1); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_l1h2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_h1l2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_h1h2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_h1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_l1l1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_l1l2_constrain_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_l1l2_constrain_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_leftkeyword_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_noexpr1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_expr1inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_noexpr2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_expr2inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_noexpr1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_expr1inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_noexpr2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_expr2inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_eq2_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_noteq); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_noteq_noexpr1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_noteq_expr1inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_noteq_noexpr2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_noteq_expr2inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_noteq_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_not); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_not_noexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_not_emptyparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_not_extraparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_or); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_or_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_or_noexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_or_emptyfirstparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_or_missingsecondexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_or_emptysecondparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_or_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_and); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_and_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_and_noexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_and_emptyfirstparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_and_missingsecondexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_and_emptysecondparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_and_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_dom); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_dom_noexpr1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_dom_expr1inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_dom_noexpr2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_dom_expr2inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_dom_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_domby); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_domby_noexpr1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_domby_expr1inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_domby_noexpr2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_domby_expr2inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_domby_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_incomp); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_incomp_noexpr1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_incomp_expr1inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_incomp_noexpr2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_incomp_expr2inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_incomp_extraexpr_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_stacknull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_operatorinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expr_stack_incorrectcall_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_roleallow); + SUITE_ADD_TEST(suite, test_cil_gen_roleallow_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roleallow_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roleallow_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roleallow_srcnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roleallow_tgtnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roleallow_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_roleallow); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_roleallow_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_norole1_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_role1_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_norole2_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_role2_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_rolebounds_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_rolebounds); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_rolebounds_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_avrule); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_permset); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_permset_anon); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_sourceparens); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_sourceemptyparen_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_targetparens); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_targetemptyparen_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_sourcedomainnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_targetdomainnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_objectclassnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_permsnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_avrule_twolists_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_allow); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_allow_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_auditallow); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_auditallow_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_dontaudit); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_dontaudit_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_neverallow); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_avrule_neverallow_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition_srcnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition_tgtnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition_objnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition_resultnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_transition_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type_rule_transition); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type_rule_transition_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change_srcnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change_tgtnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change_objnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change_resultnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_change_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type_rule_change); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type_rule_change_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_srcnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_tgtnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_objnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_resultnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_type_rule_member_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type_rule_member); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_type_rule_member_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_user); + SUITE_ADD_TEST(suite, test_cil_gen_user_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_user_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_user_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_user_nouser_neg); + SUITE_ADD_TEST(suite, test_cil_gen_user_xsinfo_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_user); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_user_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_userlevel); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_anon_level); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_anon_level_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_usernull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_userrange_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_levelnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_levelrangeempty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userlevel_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userlevel); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userlevel_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_userrange_named); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_anon); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_usernull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_anonuser_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_rangenamenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_anonrangeinvalid_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_anonrangeempty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrange_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userrange); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userrange_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_sensitivity); + SUITE_ADD_TEST(suite, test_cil_gen_sensitivity_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensitivity_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensitivity_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensitivity_sensnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensitivity_senslist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensitivity_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sensitivity); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sensitivity_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_sensalias); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_sensnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_senslist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_aliasnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_aliaslist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_sensalias_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sensalias); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_sensalias_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_category); + SUITE_ADD_TEST(suite, test_cil_gen_category_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_category_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_category_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_category_catnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_category_catlist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_category_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_category); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_category_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_catset); + SUITE_ADD_TEST(suite, test_cil_gen_catset_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_namenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_setnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_namelist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_nodefail_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_notset_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catset_settolistfail_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catset); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catset_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_catalias); + SUITE_ADD_TEST(suite, test_cil_gen_catalias_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catalias_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catalias_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catalias_catnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catalias_aliasnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catalias_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catalias); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catalias_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_catrange); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_norange_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_emptyrange_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_extrarange_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catrange_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catrange); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catrange_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_roletype); + SUITE_ADD_TEST(suite, test_cil_gen_roletype_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletype_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletype_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletype_empty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletype_rolelist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletype_roletype_sublist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_roletype_typelist_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_roletype); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_roletype_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_userrole); + SUITE_ADD_TEST(suite, test_cil_gen_userrole_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrole_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrole_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrole_empty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrole_userlist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrole_userrole_sublist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_userrole_rolelist_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userrole); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_userrole_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_classcommon); + SUITE_ADD_TEST(suite, test_cil_gen_classcommon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classcommon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classcommon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classcommon_missingclassname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classcommon_noperms_neg); + SUITE_ADD_TEST(suite, test_cil_gen_classcommon_extraperms_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_classcommon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_classcommon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_catorder); + SUITE_ADD_TEST(suite, test_cil_gen_catorder_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catorder_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catorder_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catorder_missingcats_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catorder_nosublist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_catorder_nestedcat_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catorder); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_catorder_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_dominance); + SUITE_ADD_TEST(suite, test_cil_gen_dominance_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_dominance_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_dominance_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_dominance_nosensitivities_neg); + SUITE_ADD_TEST(suite, test_cil_gen_dominance_nosublist_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_dominance); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_dominance_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_senscat); + SUITE_ADD_TEST(suite, test_cil_gen_senscat_nosublist); + SUITE_ADD_TEST(suite, test_cil_gen_senscat_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_senscat_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_senscat_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_senscat_nosensitivities_neg); + SUITE_ADD_TEST(suite, test_cil_gen_senscat_sublist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_senscat_nocat_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_senscat); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_senscat_neg); + + SUITE_ADD_TEST(suite, test_cil_fill_level); + SUITE_ADD_TEST(suite, test_cil_fill_level_sensnull_neg); + SUITE_ADD_TEST(suite, test_cil_fill_level_levelnull_neg); + SUITE_ADD_TEST(suite, test_cil_fill_level_nocat); + SUITE_ADD_TEST(suite, test_cil_fill_level_emptycat_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_level); + SUITE_ADD_TEST(suite, test_cil_gen_level_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_emptysensparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_emptycat_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_nosens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_level_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_level); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_level_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_levelrange); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_rangeinvalid_neg); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_namenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_rangenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_rangeempty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_levelrange_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_levelrange); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_levelrange_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_constrain); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_classset_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_classset_noperm_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_classset_noclass_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_permset_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_permset_noclass_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_permset_noperm_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_expression_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_constrain_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_constrain); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_constrain_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_mlsconstrain); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_mlsconstrain_neg); + + SUITE_ADD_TEST(suite, test_cil_fill_context); + SUITE_ADD_TEST(suite, test_cil_fill_context_unnamedlvl); + SUITE_ADD_TEST(suite, test_cil_fill_context_nocontext_neg); + SUITE_ADD_TEST(suite, test_cil_fill_context_nouser_neg); + SUITE_ADD_TEST(suite, test_cil_fill_context_norole_neg); + SUITE_ADD_TEST(suite, test_cil_fill_context_notype_neg); + SUITE_ADD_TEST(suite, test_cil_fill_context_nolowlvl_neg); + SUITE_ADD_TEST(suite, test_cil_fill_context_nohighlvl_neg); + SUITE_ADD_TEST(suite, test_cil_fill_context_unnamedlvl_nocontextlow_neg); + SUITE_ADD_TEST(suite, test_cil_fill_context_unnamedlvl_nocontexthigh_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_context); + SUITE_ADD_TEST(suite, test_cil_gen_context_notinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_extralevel_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_emptycontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_doubleparen_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_norole_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_roleinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_notype_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_typeinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_nolevels_neg); +// SUITE_ADD_TEST(suite, test_cil_gen_context_nosecondlevel_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_nouser_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_context_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_context); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_context_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_filecon_file); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_dir); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_char); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_block); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_socket); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_pipe); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_symlink); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_any); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_anon_context); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_str1null_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_str1_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_str2null_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_str2_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_classnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_class_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_contextnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_context_neg); + SUITE_ADD_TEST(suite, test_cil_gen_filecon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_filecon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_filecon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_portcon_udp); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_tcp); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_unknownprotocol_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_anon_context); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_portrange); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_portrange_one_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_portrange_morethanone_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_singleport_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_lowport_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_highport_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_str1null_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_str1parens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_portnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_contextnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_context_neg); + SUITE_ADD_TEST(suite, test_cil_gen_portcon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_portcon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_portcon_neg); + + SUITE_ADD_TEST(suite, test_cil_fill_ipaddr); + SUITE_ADD_TEST(suite, test_cil_fill_ipaddr_addrnodenull_neg); + SUITE_ADD_TEST(suite, test_cil_fill_ipaddr_addrnull_neg); + SUITE_ADD_TEST(suite, test_cil_fill_ipaddr_addrinparens_neg); + SUITE_ADD_TEST(suite, test_cil_fill_ipaddr_extra_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_nodecon); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_anon_context); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_ipnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_ipanon); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_ipanon_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_netmasknull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_netmaskanon); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_netmaskanon_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_contextnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_context_neg); + SUITE_ADD_TEST(suite, test_cil_gen_nodecon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_nodecon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_nodecon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_genfscon); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_anon_context); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_typenull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_typeparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_pathnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_pathparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_contextnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_context_neg); + SUITE_ADD_TEST(suite, test_cil_gen_genfscon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_genfscon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_genfscon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_netifcon); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_nested); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_nested_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_nested_emptysecondlist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_extra_nested_secondlist_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_nested_missingobjects_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_nested_secondnested_missingobjects_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_ethmissing_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_interfacemissing_neg); + SUITE_ADD_TEST(suite, test_cil_gen_netifcon_packetmissing_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_netifcon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_netifcon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_pirqnotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_nopirq_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_pirqrange_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_nocontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_anoncontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pirqcon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_pirqcon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_pirqcon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_iomemrange); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_iomemrange_firstnotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_iomemrange_secondnotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_iomemrange_empty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_iomemrange_singleiomem_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_iomemrange_morethantwoiomem_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_iomemnotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_noiomem_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_nocontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_anoncontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_iomemcon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_iomemcon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_iomemcon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_ioportrange); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_ioportrange_firstnotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_ioportrange_secondnotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_ioportrange_empty_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_ioportrange_singleioport_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_ioportrange_morethantwoioport_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_ioportnotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_noioport_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_nocontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_anoncontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ioportcon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_ioportcon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_ioportcon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_pcidevicenotint_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_nopcidevice_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_pcidevicerange_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_nocontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_anoncontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_pcidevicecon_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_pcidevicecon); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_pcidevicecon_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_anoncontext); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_anoncontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_xattr); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_task); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_transition); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_invalidtype_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_notype_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_typeinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_nofilesystem_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_filesysteminparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_nocontext_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_emptyconparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_fsuse_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_fsuse); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_fsuse_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_macro_noparams); + SUITE_ADD_TEST(suite, test_cil_gen_macro_type); + SUITE_ADD_TEST(suite, test_cil_gen_macro_role); + SUITE_ADD_TEST(suite, test_cil_gen_macro_user); + SUITE_ADD_TEST(suite, test_cil_gen_macro_sensitivity); + SUITE_ADD_TEST(suite, test_cil_gen_macro_category); + SUITE_ADD_TEST(suite, test_cil_gen_macro_catset); + SUITE_ADD_TEST(suite, test_cil_gen_macro_level); + SUITE_ADD_TEST(suite, test_cil_gen_macro_class); + SUITE_ADD_TEST(suite, test_cil_gen_macro_classmap); + SUITE_ADD_TEST(suite, test_cil_gen_macro_permset); + SUITE_ADD_TEST(suite, test_cil_gen_macro_duplicate); + SUITE_ADD_TEST(suite, test_cil_gen_macro_duplicate_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_unknown_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_unnamed_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_noparam_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_nosecondparam_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_noparam_name_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_emptyparam_neg); + SUITE_ADD_TEST(suite, test_cil_gen_macro_paramcontainsperiod_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_macro); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_macro_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_macro_nested_macro_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_macro_nested_tunif_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_call); + SUITE_ADD_TEST(suite, test_cil_gen_call_noargs); + SUITE_ADD_TEST(suite, test_cil_gen_call_anon); + SUITE_ADD_TEST(suite, test_cil_gen_call_empty_call_neg); + SUITE_ADD_TEST(suite, test_cil_gen_call_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_call_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_call_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_call_name_inparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_call_noname_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_call); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_call_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_optional); + SUITE_ADD_TEST(suite, test_cil_gen_optional_emptyoptional); + SUITE_ADD_TEST(suite, test_cil_gen_optional_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_optional_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_optional_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_optional_unnamed_neg); + SUITE_ADD_TEST(suite, test_cil_gen_optional_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_optional_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_optional_norule_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_optional); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_optional_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_policycap); + SUITE_ADD_TEST(suite, test_cil_gen_policycap_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_policycap_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_policycap_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_policycap_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_policycap_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_policycap_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_policycap); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_policycap_neg); + + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_ipv4); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_ipv4_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_ipv6); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_ipv6_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_noname_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_nameinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_noip_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_ipinparens_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_extra_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_dbnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_currnull_neg); + SUITE_ADD_TEST(suite, test_cil_gen_ipaddr_astnull_neg); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_ipaddr); + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_gen_ipaddr_neg); + + SUITE_ADD_TEST(suite, test_cil_build_ast_node_helper_extraargsnull_neg); + + SUITE_ADD_TEST(suite, test_cil_build_ast_last_child_helper); + SUITE_ADD_TEST(suite, test_cil_build_ast_last_child_helper_extraargsnull_neg); + + return suite; +} + +CuSuite* CilTreeGetSuite(void) { + CuSuite* suite = CuSuiteNew(); + + /* CilTest.c */ + SUITE_ADD_TEST(suite, test_symtab_init); + SUITE_ADD_TEST(suite, test_symtab_init_no_table_neg); + + + /* test_cil.c */ + SUITE_ADD_TEST(suite, test_cil_symtab_array_init); + + SUITE_ADD_TEST(suite, test_cil_db_init); + + SUITE_ADD_TEST(suite, test_cil_get_symtab_block); + SUITE_ADD_TEST(suite, test_cil_get_symtab_class); + SUITE_ADD_TEST(suite, test_cil_get_symtab_root); + SUITE_ADD_TEST(suite, test_cil_get_symtab_flavor_neg); + SUITE_ADD_TEST(suite, test_cil_get_symtab_null_neg); + SUITE_ADD_TEST(suite, test_cil_get_symtab_node_null_neg); + SUITE_ADD_TEST(suite, test_cil_get_symtab_parent_null_neg); + + + /* test_cil_list.c */ + SUITE_ADD_TEST(suite, test_cil_list_append_item); + SUITE_ADD_TEST(suite, test_cil_list_append_item_append); + SUITE_ADD_TEST(suite, test_cil_list_append_item_append_extra); + SUITE_ADD_TEST(suite, test_cil_list_append_item_listnull_neg); + SUITE_ADD_TEST(suite, test_cil_list_append_item_itemnull_neg); + SUITE_ADD_TEST(suite, test_cil_list_prepend_item_prepend); + SUITE_ADD_TEST(suite, test_cil_list_prepend_item_prepend_neg); + SUITE_ADD_TEST(suite, test_cil_list_prepend_item_listnull_neg); + SUITE_ADD_TEST(suite, test_cil_list_prepend_item_itemnull_neg); + + + /* test_cil_symtab.c */ + SUITE_ADD_TEST(suite, test_cil_symtab_insert); + + + /* test_cil_tree.c */ + SUITE_ADD_TEST(suite, test_cil_tree_init); + SUITE_ADD_TEST(suite, test_cil_tree_node_init); + + + /* test_cil_lexer.c */ + SUITE_ADD_TEST(suite, test_cil_lexer_setup); + SUITE_ADD_TEST(suite, test_cil_lexer_next); + + + /* test_cil_parser.c */ + SUITE_ADD_TEST(suite, test_cil_parser); + + + /* test_cil_fqn.c */ + SUITE_ADD_TEST(suite, test_cil_qualify_name); + SUITE_ADD_TEST(suite, test_cil_qualify_name_cil_flavor); + + /* test cil_copy_ast.c */ + SUITE_ADD_TEST(suite, test_cil_copy_list); + SUITE_ADD_TEST(suite, test_cil_copy_list_sublist); + SUITE_ADD_TEST(suite, test_cil_copy_list_sublist_extra); + SUITE_ADD_TEST(suite, test_cil_copy_list_orignull_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_block); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_block); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_block_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_perm); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_perm); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_perm_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_class); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_class); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_class_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_common); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_common); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_common_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_classcommon); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_classcommon); + + SUITE_ADD_TEST(suite, test_cil_copy_sid); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_sid); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_sid_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_sidcontext); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_sidcontext); + + SUITE_ADD_TEST(suite, test_cil_copy_user); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_user); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_user_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_role); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_role); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_role_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_userrole); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_userrole); + + SUITE_ADD_TEST(suite, test_cil_copy_type); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_type); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_type_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_typeattribute); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_typeattribute); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_typeattribute_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_typealias); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_typealias); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_typealias_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_bool); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_bool); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_bool_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_avrule); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_avrule); + + SUITE_ADD_TEST(suite, test_cil_copy_type_rule); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_type_rule); + + SUITE_ADD_TEST(suite, test_cil_copy_sens); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_sens); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_sens_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_sensalias); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_sensalias); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_sensalias_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_cat); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_cat); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_cat_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_catalias); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_catalias); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_catalias_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_senscat); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_senscat); + + SUITE_ADD_TEST(suite, test_cil_copy_catorder); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_catorder); + + SUITE_ADD_TEST(suite, test_cil_copy_dominance); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_dominance); + + SUITE_ADD_TEST(suite, test_cil_copy_level); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_level); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_level_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_fill_level); + + SUITE_ADD_TEST(suite, test_cil_copy_context); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_context); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_context_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_netifcon); + SUITE_ADD_TEST(suite, test_cil_copy_netifcon_nested); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_netifcon); + + SUITE_ADD_TEST(suite, test_cil_copy_fill_context); + SUITE_ADD_TEST(suite, test_cil_copy_fill_context_anonrange); + + SUITE_ADD_TEST(suite, test_cil_copy_call); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_call); + + SUITE_ADD_TEST(suite, test_cil_copy_optional); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_optional); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_optional_merge); + + SUITE_ADD_TEST(suite, test_cil_copy_nodecon); + SUITE_ADD_TEST(suite, test_cil_copy_nodecon_anon); + + SUITE_ADD_TEST(suite, test_cil_copy_fill_ipaddr); + + SUITE_ADD_TEST(suite, test_cil_copy_ipaddr); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_ipaddr); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_ipaddr_dup_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_conditional); + + SUITE_ADD_TEST(suite, test_cil_copy_boolif); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_boolif); + + SUITE_ADD_TEST(suite, test_cil_copy_constrain); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_mlsconstrain); + + //SUITE_ADD_TEST(suite, test_cil_copy_ast); + //SUITE_ADD_TEST(suite, test_cil_copy_ast_neg); + + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_orignull_neg); + SUITE_ADD_TEST(suite, test_cil_copy_node_helper_extraargsnull_neg); + + /* test_post.c */ + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_meta_a_not_b); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_meta_b_not_a); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_meta_a_and_b_strlen_a_greater_b); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_meta_a_and_b_strlen_b_greater_a); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_type_atype_greater_btype); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_type_btype_greater_atype); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_stemlen_a_greater_b); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_stemlen_b_greater_a); + SUITE_ADD_TEST(suite, test_cil_post_filecon_compare_equal); + + SUITE_ADD_TEST(suite, test_cil_post_genfscon_compare_atypestr_greater_btypestr); + SUITE_ADD_TEST(suite, test_cil_post_genfscon_compare_btypestr_greater_atypestr); + SUITE_ADD_TEST(suite, test_cil_post_genfscon_compare_apathstr_greater_bpathstr); + SUITE_ADD_TEST(suite, test_cil_post_genfscon_compare_bpathstr_greater_apathstr); + SUITE_ADD_TEST(suite, test_cil_post_genfscon_compare_equal); + + SUITE_ADD_TEST(suite, test_cil_post_netifcon_compare_a_greater_b); + SUITE_ADD_TEST(suite, test_cil_post_netifcon_compare_b_greater_a); + SUITE_ADD_TEST(suite, test_cil_post_netifcon_compare_equal); + + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_aipv4_bipv6); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_aipv6_bipv4); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_aipv4_greaterthan_bipv4); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_aipv4_lessthan_bipv4); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_amaskipv4_greaterthan_bmaskipv4); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_amaskipv4_lessthan_bmaskipv4); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_aipv6_greaterthan_bipv6); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_aipv6_lessthan_bipv6); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_amaskipv6_greaterthan_bmaskipv6); + SUITE_ADD_TEST(suite, test_cil_post_nodecon_compare_amaskipv6_lessthan_bmaskipv6); + + SUITE_ADD_TEST(suite, test_cil_post_fsuse_compare_type_a_greater_b); + SUITE_ADD_TEST(suite, test_cil_post_fsuse_compare_type_b_greater_a); + SUITE_ADD_TEST(suite, test_cil_post_fsuse_compare_fsstr_a_greater_b); + SUITE_ADD_TEST(suite, test_cil_post_fsuse_compare_fsstr_b_greater_a); + SUITE_ADD_TEST(suite, test_cil_post_fsuse_compare_equal); + + return suite; +} + +CuSuite* CilTestFullCil(void) { + CuSuite* suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_min_policy); + SUITE_ADD_TEST(suite, test_integration); + + return suite; +} diff --git a/kernel/libsepol/cil/test/unit/CilTest.h b/kernel/libsepol/cil/test/unit/CilTest.h new file mode 100644 index 00000000..f43b0ed2 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/CilTest.h @@ -0,0 +1,44 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef CILTEST_H_ +#define CILTEST_H_ + +#include "../../src/cil_tree.h" + +// TODO Check more in the data structures +struct cil_file_data { + char *buffer; + uint32_t file_size; +}; + +void set_cil_file_data(struct cil_file_data **); +void gen_test_tree(struct cil_tree **, char **); + +#endif diff --git a/kernel/libsepol/cil/test/unit/CuTest.c b/kernel/libsepol/cil/test/unit/CuTest.c new file mode 100644 index 00000000..9b481e3c --- /dev/null +++ b/kernel/libsepol/cil/test/unit/CuTest.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2003 Asim Jalis + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + */ + +#include +#include +#include +#include +#include +#include + +#include "CuTest.h" + +/*-------------------------------------------------------------------------* + * CuStr + *-------------------------------------------------------------------------*/ + +char* CuStrAlloc(int size) +{ + char* newStr = (char*) malloc( sizeof(char) * (size) ); + return newStr; +} + +char* CuStrCopy(const char* old) +{ + int len = strlen(old); + char* newStr = CuStrAlloc(len + 1); + strcpy(newStr, old); + return newStr; +} + +/*-------------------------------------------------------------------------* + * CuString + *-------------------------------------------------------------------------*/ + +void CuStringInit(CuString* str) +{ + str->length = 0; + str->size = STRING_MAX; + str->buffer = (char*) malloc(sizeof(char) * str->size); + str->buffer[0] = '\0'; +} + +CuString* CuStringNew(void) +{ + CuString* str = (CuString*) malloc(sizeof(CuString)); + str->length = 0; + str->size = STRING_MAX; + str->buffer = (char*) malloc(sizeof(char) * str->size); + str->buffer[0] = '\0'; + return str; +} + +void CuStringDelete(CuString *str) +{ + if (!str) return; + free(str->buffer); + free(str); +} + +void CuStringResize(CuString* str, int newSize) +{ + str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize); + str->size = newSize; +} + +void CuStringAppend(CuString* str, const char* text) +{ + int length; + + if (text == NULL) { + text = "NULL"; + } + + length = strlen(text); + if (str->length + length + 1 >= str->size) + CuStringResize(str, str->length + length + 1 + STRING_INC); + str->length += length; + strcat(str->buffer, text); +} + +void CuStringAppendChar(CuString* str, char ch) +{ + char text[2]; + text[0] = ch; + text[1] = '\0'; + CuStringAppend(str, text); +} + +__attribute__ ((format (printf, 2, 3))) void CuStringAppendFormat(CuString* str, const char* format, ...) +{ + va_list argp; + char buf[HUGE_STRING_LEN]; + va_start(argp, format); + vsprintf(buf, format, argp); + va_end(argp); + CuStringAppend(str, buf); +} + +void CuStringInsert(CuString* str, const char* text, int pos) +{ + int length = strlen(text); + if (pos > str->length) + pos = str->length; + if (str->length + length + 1 >= str->size) + CuStringResize(str, str->length + length + 1 + STRING_INC); + memmove(str->buffer + pos + length, str->buffer + pos, (str->length - pos) + 1); + str->length += length; + memcpy(str->buffer + pos, text, length); +} + +/*-------------------------------------------------------------------------* + * CuTest + *-------------------------------------------------------------------------*/ + +void CuTestInit(CuTest* t, const char* name, TestFunction function) +{ + t->name = CuStrCopy(name); + t->failed = 0; + t->ran = 0; + t->message = NULL; + t->function = function; + t->jumpBuf = NULL; +} + +CuTest* CuTestNew(const char* name, TestFunction function) +{ + CuTest* tc = CU_ALLOC(CuTest); + CuTestInit(tc, name, function); + return tc; +} + +void CuTestDelete(CuTest *t) +{ + if (!t) return; + free(t->name); + free(t); +} + +void CuTestRun(CuTest* tc) +{ + jmp_buf buf; + tc->jumpBuf = &buf; + if (setjmp(buf) == 0) + { + tc->ran = 1; + (tc->function)(tc); + } + tc->jumpBuf = 0; +} + +static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string) +{ + char buf[HUGE_STRING_LEN]; + + sprintf(buf, "%s:%d: ", file, line); + CuStringInsert(string, buf, 0); + + tc->failed = 1; + tc->message = string->buffer; + if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0); +} + +void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message) +{ + CuString string; + + CuStringInit(&string); + if (message2 != NULL) + { + CuStringAppend(&string, message2); + CuStringAppend(&string, ": "); + } + CuStringAppend(&string, message); + CuFailInternal(tc, file, line, &string); +} + +void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition) +{ + if (condition) return; + CuFail_Line(tc, file, line, NULL, message); +} + +void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + const char* expected, const char* actual) +{ + CuString string; + if ((expected == NULL && actual == NULL) || + (expected != NULL && actual != NULL && + strcmp(expected, actual) == 0)) + { + return; + } + + CuStringInit(&string); + if (message != NULL) + { + CuStringAppend(&string, message); + CuStringAppend(&string, ": "); + } + CuStringAppend(&string, "expected <"); + CuStringAppend(&string, expected); + CuStringAppend(&string, "> but was <"); + CuStringAppend(&string, actual); + CuStringAppend(&string, ">"); + CuFailInternal(tc, file, line, &string); +} + +void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + int expected, int actual) +{ + char buf[STRING_MAX]; + if (expected == actual) return; + sprintf(buf, "expected <%d> but was <%d>", expected, actual); + CuFail_Line(tc, file, line, message, buf); +} + +void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + double expected, double actual, double delta) +{ + char buf[STRING_MAX]; + if (fabs(expected - actual) <= delta) return; + sprintf(buf, "expected <%f> but was <%f>", expected, actual); + + CuFail_Line(tc, file, line, message, buf); +} + +void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, + void* expected, void* actual) +{ + char buf[STRING_MAX]; + if (expected == actual) return; + sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual); + CuFail_Line(tc, file, line, message, buf); +} + + +/*-------------------------------------------------------------------------* + * CuSuite + *-------------------------------------------------------------------------*/ + +void CuSuiteInit(CuSuite* testSuite) +{ + testSuite->count = 0; + testSuite->failCount = 0; + memset(testSuite->list, 0, sizeof(testSuite->list)); +} + +CuSuite* CuSuiteNew(void) +{ + CuSuite* testSuite = CU_ALLOC(CuSuite); + CuSuiteInit(testSuite); + return testSuite; +} + +void CuSuiteDelete(CuSuite *testSuite) +{ + unsigned int n; + for (n=0; n < MAX_TEST_CASES; n++) + { + if (testSuite->list[n]) + { + CuTestDelete(testSuite->list[n]); + } + } + free(testSuite); + +} + +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) +{ + assert(testSuite->count < MAX_TEST_CASES); + testSuite->list[testSuite->count] = testCase; + testSuite->count++; +} + +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2) +{ + int i; + for (i = 0 ; i < testSuite2->count ; ++i) + { + CuTest* testCase = testSuite2->list[i]; + CuSuiteAdd(testSuite, testCase); + } +} + +void CuSuiteRun(CuSuite* testSuite) +{ + int i; + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + CuTestRun(testCase); + if (testCase->failed) { testSuite->failCount += 1; } + } +} + +void CuSuiteSummary(CuSuite* testSuite, CuString* summary) +{ + int i; + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + CuStringAppend(summary, testCase->failed ? "F" : "."); + } + CuStringAppend(summary, "\n\n"); +} + +void CuSuiteDetails(CuSuite* testSuite, CuString* details) +{ + int i; + int failCount = 0; + + if (testSuite->failCount == 0) + { + int passCount = testSuite->count - testSuite->failCount; + const char* testWord = passCount == 1 ? "test" : "tests"; + CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord); + } + else + { + if (testSuite->failCount == 1) + CuStringAppend(details, "There was 1 failure:\n"); + else + CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount); + + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + if (testCase->failed) + { + failCount++; + CuStringAppendFormat(details, "%d) %s: %s\n", + failCount, testCase->name, testCase->message); + } + } + CuStringAppend(details, "\n!!!FAILURES!!!\n"); + + CuStringAppendFormat(details, "Runs: %d ", testSuite->count); + CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount); + CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount); + } +} diff --git a/kernel/libsepol/cil/test/unit/CuTest.h b/kernel/libsepol/cil/test/unit/CuTest.h new file mode 100644 index 00000000..c5ed90f8 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/CuTest.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2003 Asim Jalis + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + */ + +#ifndef CU_TEST_H +#define CU_TEST_H + +#include +#include + +#define CUTEST_VERSION "CuTest 1.5" + +/* CuString */ + +char* CuStrAlloc(int size); +char* CuStrCopy(const char* old); + +#define CU_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE))) + +#define HUGE_STRING_LEN 8192 +#define STRING_MAX 256 +#define STRING_INC 256 + +typedef struct +{ + int length; + int size; + char* buffer; +} CuString; + +void CuStringInit(CuString* str); +CuString* CuStringNew(void); +void CuStringRead(CuString* str, const char* path); +void CuStringAppend(CuString* str, const char* text); +void CuStringAppendChar(CuString* str, char ch); +void CuStringAppendFormat(CuString* str, const char* format, ...); +void CuStringInsert(CuString* str, const char* text, int pos); +void CuStringResize(CuString* str, int newSize); +void CuStringDelete(CuString* str); + +/* CuTest */ + +typedef struct CuTest CuTest; + +typedef void (*TestFunction)(CuTest *); + +struct CuTest +{ + char* name; + TestFunction function; + int failed; + int ran; + const char* message; + jmp_buf *jumpBuf; +}; + +void CuTestInit(CuTest* t, const char* name, TestFunction function); +CuTest* CuTestNew(const char* name, TestFunction function); +void CuTestRun(CuTest* tc); +void CuTestDelete(CuTest *t); + +/* Internal versions of assert functions -- use the public versions */ +void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message); +void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition); +void CuAssertStrEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + const char* expected, const char* actual); +void CuAssertIntEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + int expected, int actual); +void CuAssertDblEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + double expected, double actual, double delta); +void CuAssertPtrEquals_LineMsg(CuTest* tc, + const char* file, int line, const char* message, + void* expected, void* actual); + +/* public assert functions */ + +#define CuFail(tc, ms) CuFail_Line( (tc), __FILE__, __LINE__, NULL, (ms)) +#define CuAssert(tc, ms, cond) CuAssert_Line((tc), __FILE__, __LINE__, (ms), (cond)) +#define CuAssertTrue(tc, cond) CuAssert_Line((tc), __FILE__, __LINE__, "assert failed", (cond)) + +#define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertStrEquals_Msg(tc,ms,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) +#define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) +#define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) +#define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl)) +#define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertPtrEquals_Msg(tc,ms,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) + +#define CuAssertPtrNotNull(tc,p) CuAssert_Line((tc),__FILE__,__LINE__,"null pointer unexpected",(p != NULL)) +#define CuAssertPtrNotNullMsg(tc,msg,p) CuAssert_Line((tc),__FILE__,__LINE__,(msg),(p != NULL)) + +/* CuSuite */ + +#define MAX_TEST_CASES 1024 + +#define SUITE_ADD_TEST(SUITE,TEST) CuSuiteAdd(SUITE, CuTestNew(#TEST, TEST)) + +typedef struct +{ + int count; + CuTest* list[MAX_TEST_CASES]; + int failCount; + +} CuSuite; + + +void CuSuiteInit(CuSuite* testSuite); +CuSuite* CuSuiteNew(void); +void CuSuiteDelete(CuSuite *testSuite); +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase); +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2); +void CuSuiteRun(CuSuite* testSuite); +void CuSuiteSummary(CuSuite* testSuite, CuString* summary); +void CuSuiteDetails(CuSuite* testSuite, CuString* details); + +#endif /* CU_TEST_H */ diff --git a/kernel/libsepol/cil/test/unit/test_cil.c b/kernel/libsepol/cil/test/unit/test_cil.c new file mode 100644 index 00000000..7b575252 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil.c @@ -0,0 +1,179 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "test_cil.h" + +#include "../../src/cil_internal.h" +#include "../../src/cil_tree.h" + +void test_cil_symtab_array_init(CuTest *tc) { + struct cil_db *test_new_db; + test_new_db = malloc(sizeof(*test_new_db)); + + cil_symtab_array_init(test_new_db->symtab, cil_sym_sizes[CIL_SYM_ARRAY_ROOT]); + CuAssertPtrNotNull(tc, test_new_db->symtab); + + free(test_new_db); +} + +void test_cil_db_init(CuTest *tc) { + struct cil_db *test_db; + + cil_db_init(&test_db); + + CuAssertPtrNotNull(tc, test_db->ast); + CuAssertPtrNotNull(tc, test_db->symtab); + CuAssertPtrNotNull(tc, test_db->symtab); +} + +// TODO: Reach SEPOL_ERR return in cil_db_init ( currently can't produce a method to do so ) + +void test_cil_get_symtab_block(CuTest *tc) { + symtab_t *symtab = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->parent->flavor = CIL_BLOCK; + test_ast_node->line = 1; + + int rc = cil_get_symtab(test_db, test_ast_node->parent, &symtab, CIL_SYM_BLOCKS); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, symtab); +} + +void test_cil_get_symtab_class(CuTest *tc) { + symtab_t *symtab = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->parent->flavor = CIL_CLASS; + test_ast_node->line = 1; + + int rc = cil_get_symtab(test_db, test_ast_node->parent, &symtab, CIL_SYM_BLOCKS); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, symtab); +} + +void test_cil_get_symtab_root(CuTest *tc) { + symtab_t *symtab = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->parent->flavor = CIL_ROOT; + test_ast_node->line = 1; + + int rc = cil_get_symtab(test_db, test_ast_node->parent, &symtab, CIL_SYM_BLOCKS); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, symtab); +} + +void test_cil_get_symtab_flavor_neg(CuTest *tc) { + symtab_t *symtab = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->parent->flavor = 1234567; + test_ast_node->line = 1; + + int rc = cil_get_symtab(test_db, test_ast_node->parent, &symtab, CIL_SYM_BLOCKS); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertPtrEquals(tc, symtab, NULL); +} + +void test_cil_get_symtab_null_neg(CuTest *tc) { + symtab_t *symtab = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = NULL; + test_ast_node->line = 1; + + int rc = cil_get_symtab(test_db, test_ast_node->parent, &symtab, CIL_SYM_BLOCKS); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertPtrEquals(tc, symtab, NULL); +} + +void test_cil_get_symtab_node_null_neg(CuTest *tc) { + symtab_t *symtab = NULL; + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_get_symtab(test_db, test_ast_node, &symtab, CIL_SYM_BLOCKS); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertPtrEquals(tc, symtab, NULL); + CuAssertPtrEquals(tc, test_ast_node, NULL); +} + +void test_cil_get_symtab_parent_null_neg(CuTest *tc) { + symtab_t *symtab = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = NULL; + test_ast_node->line = 1; + + int rc = cil_get_symtab(test_db, test_ast_node->parent, &symtab, CIL_SYM_BLOCKS); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertPtrEquals(tc, symtab, NULL); +} + diff --git a/kernel/libsepol/cil/test/unit/test_cil.h b/kernel/libsepol/cil/test/unit/test_cil.h new file mode 100644 index 00000000..285b4ff6 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_H_ +#define TEST_CIL_H_ + +#include "CuTest.h" + +void test_cil_symtab_array_init(CuTest *); +void test_cil_symtab_array_init_null_symtab_neg(CuTest *); +void test_cil_db_init(CuTest *); +void test_cil_get_symtab_block(CuTest *); +void test_cil_get_symtab_class(CuTest *); +void test_cil_get_symtab_root(CuTest *); +void test_cil_get_symtab_flavor_neg(CuTest *); +void test_cil_get_symtab_null_neg(CuTest *); +void test_cil_get_symtab_node_null_neg(CuTest *); +void test_cil_get_symtab_parent_null_neg(CuTest *); + +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_build_ast.c b/kernel/libsepol/cil/test/unit/test_cil_build_ast.c new file mode 100644 index 00000000..f8cef715 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_build_ast.c @@ -0,0 +1,19179 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "CilTest.h" +#include "test_cil_build_ast.h" + +#include "../../src/cil_build_ast.h" + +#include "../../src/cil_tree.h" + +int __cil_build_ast_node_helper(struct cil_tree_node *, uint32_t *, void *); +int __cil_build_ast_last_child_helper(__attribute__((unused)) struct cil_tree_node *parse_current, void *); +//int __cil_build_constrain_tree(struct cil_tree_node *parse_current, struct cil_tree_node *expr_root); + +struct cil_args_build { + struct cil_tree_node *ast; + struct cil_db *db; + struct cil_tree_node *macro; + struct cil_tree_node *tifstack; +}; + +struct cil_args_build *gen_build_args(struct cil_tree_node *node, struct cil_db *db, struct cil_tree_node * macro, struct cil_tree_node *tifstack) +{ + struct cil_args_build *args = cil_malloc(sizeof(*args)); + args->ast = node; + args->db = db; + args->macro = macro; + args->tifstack = tifstack; + + return args; +} + +// First seen in cil_gen_common +void test_cil_parse_to_list(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + struct cil_avrule *test_avrule; + cil_avrule_init(&test_avrule); + test_avrule->rule_kind = CIL_AVRULE_ALLOWED; + test_avrule->src_str = cil_strdup(test_current->next->data); + test_avrule->tgt_str = cil_strdup(test_current->next->next->data); + + cil_classpermset_init(&test_avrule->classpermset); + + test_avrule->classpermset->class_str = cil_strdup(test_current->next->next->next->cl_head->data); + + cil_permset_init(&test_avrule->classpermset->permset); + + cil_list_init(&test_avrule->classpermset->permset->perms_list_str); + + test_current = test_current->next->next->next->cl_head->next->cl_head; + + int rc = cil_parse_to_list(test_current, test_avrule->classpermset->permset->perms_list_str, CIL_AST_STR); + CuAssertIntEquals(tc, SEPOL_OK, rc); + + cil_destroy_avrule(test_avrule); +} + +void test_cil_parse_to_list_currnull_neg(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + struct cil_avrule *test_avrule; + cil_avrule_init(&test_avrule); + test_avrule->rule_kind = CIL_AVRULE_ALLOWED; + test_avrule->src_str = cil_strdup(test_current->next->data); + test_avrule->tgt_str = cil_strdup(test_current->next->next->data); + + cil_classpermset_init(&test_avrule->classpermset); + + test_avrule->classpermset->class_str = cil_strdup(test_current->next->next->next->cl_head->data); + + cil_permset_init(&test_avrule->classpermset->permset); + + cil_list_init(&test_avrule->classpermset->permset->perms_list_str); + + test_current = NULL; + + int rc = cil_parse_to_list(test_current, test_avrule->classpermset->permset->perms_list_str, CIL_AST_STR); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + + cil_destroy_avrule(test_avrule); +} + +void test_cil_parse_to_list_listnull_neg(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + struct cil_avrule *test_avrule; + cil_avrule_init(&test_avrule); + test_avrule->rule_kind = CIL_AVRULE_ALLOWED; + test_avrule->src_str = cil_strdup(test_current->next->data); + test_avrule->tgt_str = cil_strdup(test_current->next->next->data); + + cil_classpermset_init(&test_avrule->classpermset); + + test_avrule->classpermset->class_str = cil_strdup(test_current->next->next->next->cl_head->data); + + cil_permset_init(&test_avrule->classpermset->permset); + + test_current = test_current->next->next->next->cl_head->next->cl_head; + + int rc = cil_parse_to_list(test_current, test_avrule->classpermset->permset->perms_list_str, CIL_AST_STR); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + + cil_destroy_avrule(test_avrule); +} + +void test_cil_set_to_list(CuTest *tc) { + char *line[] = {"(", "foo1", "foo2", "(", "foo3", ")", ")", NULL}; + + struct cil_tree *test_tree; + struct cil_list *cil_l = NULL; + struct cil_list *sub_list = NULL; + + gen_test_tree(&test_tree, line); + cil_list_init(&cil_l); + + int rc = cil_set_to_list(test_tree->root->cl_head, cil_l, 1); + sub_list = (struct cil_list *)cil_l->head->next->next->data; + + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertStrEquals(tc, "foo1", (char*)cil_l->head->data); + CuAssertStrEquals(tc, "foo2", (char*)cil_l->head->next->data); + CuAssertStrEquals(tc, "foo3", (char*)sub_list->head->data); +} + +void test_cil_set_to_list_tree_node_null_neg(CuTest *tc) { + struct cil_list *cil_l = NULL; + int rc = cil_set_to_list(NULL, cil_l, 1); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_set_to_list_cl_head_null_neg(CuTest *tc) { + char *line[] = {"(", "foo", "bar", ")", NULL}; + + struct cil_list *cil_l; + struct cil_tree *test_tree = NULL; + + cil_list_init(&cil_l); + gen_test_tree(&test_tree, line); + test_tree->root->cl_head = NULL; + + int rc = cil_set_to_list(test_tree->root, cil_l, 1); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_set_to_list_listnull_neg(CuTest *tc) { + char *line[] = {"(", "foo1", "foo2", "foo3", ")", NULL}; + + struct cil_tree *test_tree = NULL; + gen_test_tree(&test_tree, line); + + int rc = cil_set_to_list(test_tree->root, NULL, 1); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_block(CuTest *tc) { + char *line[] = {"(", "block", "a", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, ((struct cil_block*)test_ast_node->data)->is_abstract, 0); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_BLOCK); +} + +void test_cil_gen_block_justblock_neg(CuTest *tc) { + char *line[] = {"(", "block", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_block_noname_neg(CuTest *tc) { + char *line[] = {"(", "block", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_block_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "block", "foo", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_block_treenull_neg(CuTest *tc) { + char *line[] = {"(", "block", "foo", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_tree->root->cl_head->cl_head = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_block_nodenull_neg(CuTest *tc) { + char *line[] = {"(", "block", "foo", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_block_nodeparentnull_neg(CuTest *tc) { + char *line[] = {"(", "block", "foo", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = NULL; + test_ast_node->line = 1; + + int rc = cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_destroy_block(CuTest *tc) { + char *line[] = {"(", "block", "a", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + + cil_destroy_block((struct cil_block*)test_ast_node->data); + CuAssertPtrEquals(tc, NULL,test_ast_node->data); +} + +void test_cil_gen_blockinherit(CuTest *tc) { + char *line[] = {"(", "blockinherit", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_blockinherit(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_blockinherit_namelist_neg(CuTest *tc) { + char *line[] = {"(", "blockinherit", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_blockinherit(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_blockinherit_namenull_neg(CuTest *tc) { + char *line[] = {"(", "blockinherit", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_blockinherit(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_blockinherit_extra_neg(CuTest *tc) { + char *line[] = {"(", "blockinherit", "foo", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_blockinherit(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_blockinherit_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "blockinherit", "foo", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_blockinherit(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_blockinherit_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_blockinherit(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_blockinherit_astnull_neg(CuTest *tc) { + char *line[] = {"(", "blockinherit", "foo", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_blockinherit(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_perm(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_class *new_node; + cil_class_init(&new_node); + + struct cil_tree_node *new_tree_node; + cil_tree_node_init(&new_tree_node); + new_tree_node->data = new_node; + new_tree_node->flavor = CIL_CLASS; + + test_ast_node->parent = new_tree_node; + test_ast_node->line = 1; + + int rc = cil_gen_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node); + int rc1 = cil_gen_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head->next, test_ast_node); + int rc2 = cil_gen_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head->next->next, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc1); + CuAssertIntEquals(tc, SEPOL_OK, rc2); +} + +void test_cil_gen_perm_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + int rc = 0; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_current_perm = NULL; + struct cil_tree_node *test_new_ast = NULL; + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + test_current_perm = test_tree->root->cl_head->cl_head->next->next->cl_head; + + cil_tree_node_init(&test_new_ast); + test_new_ast->parent = test_ast_node; + test_new_ast->line = test_current_perm->line; + + rc = cil_gen_perm(test_db, test_current_perm, test_new_ast); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_perm_currnull_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + int rc = 0; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_current_perm = NULL; + struct cil_tree_node *test_new_ast = NULL; + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_current_perm = NULL; + + cil_tree_node_init(&test_new_ast); + test_new_ast->parent = test_ast_node; + + rc = cil_gen_perm(test_db, test_current_perm, test_new_ast); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_perm_astnull_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_class *new_node; + cil_class_init(&new_node); + + struct cil_tree_node *new_tree_node; + cil_tree_node_init(&new_tree_node); + new_tree_node->data = new_node; + new_tree_node->flavor = CIL_CLASS; + + int rc = cil_gen_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_perm_nodenull_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + int rc = 0; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_current_perm = NULL; + struct cil_tree_node *test_new_ast = NULL; + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_current_perm = test_tree->root->cl_head->cl_head->next->next->cl_head; + + cil_tree_node_init(&test_new_ast); + test_new_ast->parent = test_ast_node; + test_new_ast->line = test_current_perm->line; + + rc = cil_gen_perm(test_db, test_current_perm, test_new_ast); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_permset_noname_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "(", "foo", ")", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset_noperms_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset_emptyperms_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset_extra_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "write", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_permset_astnull_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_permset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_perm_nodes(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + char *test_key = test_tree->root->cl_head->cl_head->next->data; + struct cil_class *test_cls; + cil_class_init(&test_cls); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_insert(&test_db->symtab[CIL_SYM_CLASSES], (hashtab_key_t)test_key, (struct cil_symtab_datum*)test_cls, test_ast_node); + + test_ast_node->data = test_cls; + test_ast_node->flavor = CIL_CLASS; + + int rc = cil_gen_perm_nodes(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node, CIL_PERM); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_perm_nodes_failgen_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + char *test_key = test_tree->root->cl_head->cl_head->next->data; + struct cil_class *test_cls; + cil_class_init(&test_cls); + + cil_symtab_destroy(&test_cls->perms); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_insert(&test_db->symtab[CIL_SYM_CLASSES], (hashtab_key_t)test_key, (struct cil_symtab_datum*)test_cls, test_ast_node); + + test_ast_node->data = test_cls; + test_ast_node->flavor = CIL_CLASS; + + int rc = cil_gen_perm_nodes(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node, CIL_PERM); + CuAssertIntEquals(tc, SEPOL_ENOMEM, rc); +} + +void test_cil_gen_perm_nodes_inval_perm_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "(", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + char *test_key = test_tree->root->cl_head->cl_head->next->data; + struct cil_class *test_cls; + cil_class_init(&test_cls); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_insert(&test_db->symtab[CIL_SYM_CLASSES], (hashtab_key_t)test_key, (struct cil_symtab_datum*)test_cls, test_ast_node); + + test_ast_node->data = test_cls; + test_ast_node->flavor = CIL_CLASS; + + int rc = cil_gen_perm_nodes(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node, CIL_PERM); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_permset(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_permset *permset; + cil_permset_init(&permset); + + int rc = cil_fill_permset(test_tree->root->cl_head->cl_head->next->next->cl_head, permset); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_permset_sublist_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_permset *permset; + cil_permset_init(&permset); + + int rc = cil_fill_permset(test_tree->root->cl_head->cl_head->next->next->cl_head, permset); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_permset_startpermnull_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_permset *permset; + cil_permset_init(&permset); + + int rc = cil_fill_permset(test_tree->root->cl_head->cl_head->next->next->cl_head, permset); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_permset_permsetnull_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_permset *permset = NULL; + + int rc = cil_fill_permset(test_tree->root->cl_head->cl_head->next->next->cl_head, permset); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_in(CuTest *tc) { + char *line[] = {"(", "in", "foo", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_in(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_in_blockstrnull_neg(CuTest *tc) { + char *line[] = {"(", "in", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_in(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_in_extra_neg(CuTest *tc) { + char *line[] = {"(", "in", "foo", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_in(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_in_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "in", "foo", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_in(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_in_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_in(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_in_astnull_neg(CuTest *tc) { + char *line[] = {"(", "in", "foo", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_in(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->cl_tail); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_CLASS); +} + +void test_cil_gen_class_noname_neg(CuTest *tc) { + char *line[] = {"(", "class", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_nodenull_neg(CuTest *tc) { + char *line[] = {"(", "class", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "class", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_currnull_neg(CuTest *tc) { + char *line[] = {"(", "class", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_tree->root->cl_head->cl_head = NULL; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_noclass_neg(CuTest *tc) { + char *line[] = {"(", "test", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_noclassname_neg(CuTest *tc) { + char *line[] = {"(", "class", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_namesublist_neg(CuTest *tc) { + char *line[] = {"(", "class", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_noperms(CuTest *tc) { + char *line[] = {"(", "class", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_class_permsnotinlist_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "read", "write", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_extrapermlist_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", "(", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_class_listinlist_neg(CuTest *tc) { + char *line[] = {"(", "class", "test", "(", "read", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_classpermset_anonperms(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_classpermset_anonperms_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "(", "write", "(", "extra", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_classpermset_namedperms(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "perms", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_classpermset_extra_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "(", "write", ")", "extra", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_classpermset_emptypermslist_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "(", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_classpermset_noperms_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_classpermset_noclass_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_classpermset_classnodenull_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_classpermset_cpsnull_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_classpermset *cps = NULL; + + int rc = cil_fill_classpermset(test_tree->root->cl_head->cl_head->next->next->cl_head, cps); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_classpermset_noname_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "(", "foo", ")", "(", "read", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_noclass_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_noperms_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", "(", "char", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_emptyperms_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_extra_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", "(", "read", "(", "write", ")", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", "(", "read", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classpermset_astnull_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", "(", "read", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_classpermset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_perm(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_classmap *map = NULL; + cil_classmap_init(&map); + + test_ast_node->flavor = CIL_CLASSMAP; + test_ast_node->data = map; + + struct cil_tree_node *test_ast_node_a; + cil_tree_node_init(&test_ast_node_a); + + test_ast_node_a->parent = test_ast_node; + test_ast_node_a->line = test_tree->root->cl_head->cl_head->next->next->cl_head->line; + test_ast_node_a->path = test_tree->root->cl_head->cl_head->next->next->cl_head->path; + + int rc = cil_gen_classmap_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node_a); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_classmap_perm_dupeperm_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_ast_node_a; + cil_tree_node_init(&test_ast_node_a); + + test_ast_node_a->parent = test_ast_node; + test_ast_node_a->line = test_tree->root->cl_head->cl_head->next->next->cl_head->line; + test_ast_node_a->path = test_tree->root->cl_head->cl_head->next->next->cl_head->path; + + int rc = cil_gen_classmap_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node_a); + CuAssertIntEquals(tc, SEPOL_EEXIST, rc); +} + +void test_cil_gen_classmap_perm_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_ast_node_a; + cil_tree_node_init(&test_ast_node_a); + + test_ast_node_a->parent = test_ast_node; + test_ast_node_a->line = test_tree->root->cl_head->cl_head->line; + test_ast_node_a->path = test_tree->root->cl_head->cl_head->path; + + test_db = NULL; + + int rc = cil_gen_classmap_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node_a); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_perm_currnull_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_ast_node_a; + cil_tree_node_init(&test_ast_node_a); + + test_ast_node_a->parent = test_ast_node; + test_ast_node_a->line = test_tree->root->cl_head->cl_head->line; + test_ast_node_a->path = test_tree->root->cl_head->cl_head->path; + + int rc = cil_gen_classmap_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node_a); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_perm_astnull_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_ast_node_a = NULL; + + int rc = cil_gen_classmap_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node_a); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_classmap_extra_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_noname_neg(CuTest *tc) { + char *line[] = {"(", "classmap", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_emptyperms_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmap_astnull_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_classmap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmapping_anonpermset(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", + "(", "file", "(", "open", "read", "getattr", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_classmapping_anonpermset_neg(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", + "(", "file", "(", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmapping_namedpermset(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", "char_w", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_classmapping_noclassmapname_neg(CuTest *tc) { + char *line[] = {"(", "classmapping", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmapping_noclassmapperm_neg(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmapping_nopermissionsets_neg(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmapping_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", + "(", "file", "(", "open", "read", "getattr", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmapping_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classmapping_astnull_neg(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", + "(", "file", "(", "open", "read", "getattr", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_classmapping(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_common(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_COMMON); +} + +void test_cil_gen_common_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_common_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_common_astnull_neg(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_common_noname_neg(CuTest *tc) { + char *line[] = {"(", "common", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_common_twoperms_neg(CuTest *tc) { + char *line[] = {"(", "common", "foo", "(", "write", ")", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_common_permsublist_neg(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", "read", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_common_noperms_neg(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sid(CuTest *tc) { + char *line[] = {"(", "sid", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_sid_noname_neg(CuTest *tc) { + char *line[] = {"(", "sid", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sid_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "sid", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sid_extra_neg(CuTest *tc) { + char *line[] = {"(", "sid", "foo", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sid_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "sid", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sid_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sid_astnull_neg(CuTest *tc) { + char *line[] = {"(", "sid", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "(", "blah", "blah", "blah", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_SIDCONTEXT); +} + +void test_cil_gen_sidcontext_namedcontext(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "something", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_SIDCONTEXT); +} + +void test_cil_gen_sidcontext_halfcontext_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "(", "blah", "blah", "blah", "(", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext_noname_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", "(", "blah", "blah", "blah", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext_empty_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext_dblname_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "test2", "(", "blah", "blah", "blah", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "(", "blah", "blah", "blah", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext_pcurrnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sidcontext_astnodenull_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "(", "blah", "blah", "blah", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, NULL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type(CuTest *tc) { + char *line[] = {"(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TYPE); +} + +void test_cil_gen_type_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_type(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_astnull_neg(CuTest *tc) { + char *line[] = {"(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_type(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_extra_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", "bar," ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattribute(CuTest *tc) { + char *line[] = {"(", "typeattribute", "test", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattribute(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TYPEATTRIBUTE); +} + +void test_cil_gen_typeattribute_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "typeattribute", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_typeattribute(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + + +void test_cil_gen_typeattribute_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattribute(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + + +void test_cil_gen_typeattribute_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typeattribute", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_typeattribute(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattribute_extra_neg(CuTest *tc) { + char *line[] = {"(", "typeattribute", "foo", "bar," ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattribute(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds(CuTest *tc) { + char *line[] = {"(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_typebounds_notype1_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds_type1inparens_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", "(", "type_a", ")", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds_notype2_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", "type_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds_type2inparens_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", "type_a", "(", "type_b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds_extra_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", "type_a", "type_b", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typebounds_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_typebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typepermissive(CuTest *tc) { + char *line[] = {"(", "typepermissive", "type_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typepermissive(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_typepermissive_noname_neg(CuTest *tc) { + char *line[] = {"(", "typepermissive", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typepermissive(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typepermissive_typeinparens_neg(CuTest *tc) { + char *line[] = {"(", "typepermissive", "(", "type_a", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typepermissive(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typepermissive_extra_neg(CuTest *tc) { + char *line[] = {"(", "typepermissive", "type_a", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typepermissive(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typepermissive_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "typepermissive", "type_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_typepermissive(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typepermissive_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typepermissive(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typepermissive_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typepermissive", "type_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_typepermissive(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_nametypetransition_strinparens_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "(", "str", ")", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_nostr_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_srcinparens_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "(", "foo", ")", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_nosrc_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_tgtinparens_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "(", "bar", ")", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_notgt_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_classinparens_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "(", "file", ")", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_noclass_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_destinparens_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "file", "(", "foobar", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_nodest_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "file", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + + +void test_cil_gen_nametypetransition_extra_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nametypetransition_astnull_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_nametypetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "low_l", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_rangetransition_namedtransition(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "namedtrans", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_rangetransition_anon_low_l(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "(", "s0", "(", "c0", ")", ")", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_rangetransition_anon_low_l_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "(", "s0", "(", ")", ")", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_anon_high_l(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "low_l", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_rangetransition_anon_high_l_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "low_l", "(", "s0", "(", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "low_l", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_astnull_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "low_l", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_nofirsttype_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_firsttype_inparens_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "(", "type_a_t", ")", "type_b_t", "class", "(", "low_l", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_nosecondtype_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_secondtype_inparens_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "(", "type_b_t", ")", "class", "(", "low_l", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_noclass_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_class_inparens_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "(", "class", ")", "(", "low_l", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_nolevel_l_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_nolevel_h_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "low_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rangetransition_extra_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a_t", "type_b_t", "class", "(", "low_l", "high_l", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rangetransition(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_and(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_expr_stack_or(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "or", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_expr_stack_xor(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "xor", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_expr_stack_not(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "not", "foo", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_expr_stack_not_noexpr_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "not", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_not_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "not", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_eq(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "eq", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_expr_stack_neq(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "neq", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_expr_stack_nested(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "or", "(","neq", "foo", "bar", ")", "(", "eq", "baz", "boo", ")", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_expr_stack_nested_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "(","neq", "foo", "bar", ")", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_nested_emptyargs_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "eq", "(", ")", "(", ")", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_nested_missingoperator_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "or", "(","foo", "bar", ")", "(", "eq", "baz", "boo", ")", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_arg1null_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "eq", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_arg2null_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "eq", "foo", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_extraarg_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "eq", "foo", "bar", "extra", ")", + "(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_currnull_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_booleanif *bif; + cil_boolif_init(&bif); + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, &bif->expr_stack); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_expr_stack_stacknull_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "xor", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_expr_stack(test_tree->root->cl_head->cl_head->next, CIL_BOOL, NULL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_multiplebools_true(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "write", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_boolif_multiplebools_false(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", + "(", "false", "(", "allow", "foo", "bar", "(", "write", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_boolif_multiplebools_unknowncond_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", + "(", "dne", "(", "allow", "foo", "bar", "(", "write", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_true(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_boolif_false(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "false", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_boolif_unknowncond_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "dne", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_nested(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "(", "or", "foo", "bar", ")", "baz", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_boolif_nested_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "(", "or", "foo", "bar", ")", "baz", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_extra_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "(", "or", "foo", "bar", ")", "baz", "beef", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_extra_parens_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "(", "or", "foo", "bar", ")", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_nocond(CuTest *tc) { + char *line[] = {"(", "booleanif", "baz", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_boolif_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "**", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_astnull_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_nocond_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_notruelist_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_boolif_empty_cond_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_multiplebools_true(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "write", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_tunif_multiplebools_false(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", + "(", "false", "(", "allow", "foo", "bar", "(", "write", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_tunif_multiplebools_unknowncond_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", + "(", "dne", "(", "allow", "foo", "bar", "(", "write", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_true(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_tunif_false(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "false", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_tunif_unknowncond_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "dne", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_nocond(CuTest *tc) { + char *line[] = {"(", "tunableif", "baz", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_tunif_nested(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "(", "or", "foo", "bar", ")", "baz", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_tunif_nested_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "(", "or", "foo", "bar", ")", "baz", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_extra_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "(", "or", "foo", "bar", ")", "baz", "beef", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_extra_parens_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "(", "or", "foo", "bar", ")", ")", + "(", "true", "(", "allow", "foo", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "**", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_astnull_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_nocond_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_tunif_notruelist_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_tunif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_condblock_true(CuTest *tc) { + char *line[] = {"(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_condblock(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_CONDTRUE); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_condblock_false(CuTest *tc) { + char *line[] = {"(", "false", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_condblock(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_CONDFALSE); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_condblock_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "false", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_condblock(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_CONDFALSE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_condblock_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_condblock(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_CONDFALSE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_condblock_astnull_neg(CuTest *tc) { + char *line[] = {"(", "false", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_condblock(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_CONDFALSE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_condblock_nocond_neg(CuTest *tc) { + char *line[] = {"(", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_condblock(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_CONDTRUE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_condblock_extra_neg(CuTest *tc) { + char *line[] = {"(", "true", "(", "allow", "foo", "bar", "baz", "(", "read", ")", ")", "Extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_condblock(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_CONDTRUE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typealias(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertStrEquals(tc, ((struct cil_typealias*)test_ast_node->data)->type_str, test_tree->root->cl_head->cl_head->next->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TYPEALIAS); +} + +void test_cil_gen_typealias_incomplete_neg(CuTest *tc) { + char *line[] = {"(", "typealias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typealias_incomplete_neg2(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typealias_extratype_neg(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "foo", "extra_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typealias_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typealias_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typealias_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "test_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); +} + +void test_cil_gen_typeattributeset_and_two_types(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "and", "test_t", "test2_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); +} + +void test_cil_gen_typeattributeset_not(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "not", "notypes_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); +} + +void test_cil_gen_typeattributeset_exclude_attr(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "not", "attr", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); +} + +void test_cil_gen_typeattributeset_exclude_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "not", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "not", "type_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "not", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_noname_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "(", "filetypes", ")", "(", "test_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_emptylists_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_listinparens_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "(", "test_t", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_typeattributeset_extra_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "test_t", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_typeattributeset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userbounds(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_gen_userbounds_notype1_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_userbounds_type1_inparens_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", "(", "user1", ")", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_userbounds_notype2_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_userbounds_type2_inparens_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", "(", "user2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_userbounds_extra_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", "user2", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_userbounds_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_userbounds_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_userbounds_astnull_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_userbounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_role(CuTest *tc) { + char *line[] = {"(", "role", "test_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_role(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_ROLE); +} + +void test_cil_gen_role_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "role", "test_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_role(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_role_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_role(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_role_astnull_neg(CuTest *tc) { + char *line[] = {"(", "role", "test_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_role(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_role_extrarole_neg(CuTest *tc) { + char *line[] = {"(", "role", "test_r", "extra_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_role(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_role_noname_neg(CuTest *tc) { + char *line[] = {"(", "role", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_role(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletransition(CuTest *tc) { + char *line[] = {"(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_roletransition(test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_ROLETRANSITION); +} + +void test_cil_gen_roletransition_currnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletransition(NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletransition_astnull_neg (CuTest *tc) { + char *line[] = {"(", "roletransition" "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_roletransition(test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletransition_srcnull_neg(CuTest *tc) { + char *line[] = {"(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletransition(test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletransition_tgtnull_neg(CuTest *tc) { + char *line[] = {"(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next->next = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletransition(test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletransition_resultnull_neg(CuTest *tc) { + char *line[] = {"(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next->next->next->next = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletransition(test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletransition_extra_neg(CuTest *tc) { + char *line[] = {"(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletransition(test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_true(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, ((struct cil_bool*)test_ast_node->data)->value, 1); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_BOOL); +} + +void test_cil_gen_bool_tunable_true(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_TUNABLE); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, ((struct cil_bool*)test_ast_node->data)->value, 1); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TUNABLE); +} + +void test_cil_gen_bool_false(CuTest *tc) { + char *line[] = {"(", "boolean", "bar", "false", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, ((struct cil_bool*)test_ast_node->data)->value, 0); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_BOOL); +} + +void test_cil_gen_bool_tunable_false(CuTest *tc) { + char *line[] = {"(", "tunable", "bar", "false", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_TUNABLE); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, ((struct cil_bool*)test_ast_node->data)->value, 0); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TUNABLE); +} + +void test_cil_gen_bool_none_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_astnull_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_notbool_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_boolname_neg(CuTest *tc) { + char *line[] = {"(", "boolean", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_extraname_false_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "false", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_bool_extraname_true_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_t1type(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t1", "type_t", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_t1t1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t1", "t1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_t2type(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t2", "type_t", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_t2t2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t2", "t2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_r1role(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "role_r", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_r1r1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "r1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_r2role(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r2", "role_r", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_r2r2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r2", "r2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_t1t2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t1", "t2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_r1r2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "r2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_r1r2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "r2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_u1u2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "u1", "u2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_u1user(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "u1", "user_u", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_u1u1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "u1", "u1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_u2user(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "u2", "user_u", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_u2u2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "u2", "u2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_l2h2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_l2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_l1l2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "l2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_l1h1(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "h1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_l1h2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_h1l2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "h1", "l2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_h1h2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "h1", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_h1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "h1", "l1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_l1l1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "l1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_l1l2_constrain_neg(CuTest *tc) { + char *line[] = {"(", "constrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "l2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_CONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_l1l2_constrain_neg(CuTest *tc) { + char *line[] = {"(", "constrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "l2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_CONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_leftkeyword_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "h2", "h1", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_noexpr1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_expr1inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "(", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_noexpr2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_expr2inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "(", "h2", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "foo", "foo", "extra", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_noexpr1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_expr1inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "(", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_noexpr2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_expr2inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "(", "h2", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_eq2_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "foo", "foo", "extra", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_noteq(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "neq", "l2", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_noteq_noexpr1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "neq", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_noteq_expr1inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "neq", "(", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_noteq_noexpr2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "neq", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_noteq_expr2inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "neq", "l1", "(", "h2", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_noteq_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "neq", "foo", "foo", "extra", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_not(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "not", "(", "neq", "l2", "h2", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_not_noexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "not", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_not_emptyparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "not", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_not_extraparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "not", "(", "neq", "l2", "h2", ")", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_or(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "or", + "(", "neq", "l1", "l2", ")", "(", "neq", "l1", "h1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_or_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "or", + "(", "foo", ")", "(", "neq", "l1", "h1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_or_noexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "or", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_or_emptyfirstparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "or", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_or_missingsecondexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "or", "(", "foo", ")", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_or_emptysecondparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "or", "(", "foo", ")", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_or_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "or", "(", "foo", ")", "(", "foo", ")", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_and(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "and", + "(", "neq", "l1", "l2", ")", "(", "neq", "l1", "h1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_and_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "and", + "(", "foo", ")", "(", "neq", "l1", "h1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_and_noexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "and", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_and_emptyfirstparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "and", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_and_missingsecondexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "and", "(", "foo", ")", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_and_emptysecondparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "and", "(", "foo", ")", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_and_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "and", "(", "foo", ")", "(", "foo", ")", "(", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_dom(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "dom", "l2", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_dom_noexpr1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "dom", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_dom_expr1inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "dom", "(", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_dom_noexpr2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "dom", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_dom_expr2inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "dom", "l1", "(", "h2", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_dom_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "dom", "foo", "foo", "extra", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_domby(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "domby", "l2", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_domby_noexpr1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "domby", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_domby_expr1inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "domby", "(", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_domby_noexpr2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "domby", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_domby_expr2inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "domby", "l1", "(", "h2", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_domby_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "domby", "foo", "foo", "extra", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_incomp(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "incomp", "l2", "h2", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_expr_stack_incomp_noexpr1_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "incomp", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_incomp_expr1inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "incomp", "(", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_incomp_noexpr2_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "incomp", "l1", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_incomp_expr2inparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "incomp", "l1", "(", "h2", ")", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_incomp_extraexpr_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "incomp", "foo", "foo", "extra", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_currnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_stacknull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t1", "type_t", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, NULL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_operatorinparens_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "(", "eq", ")", "t1", "type_t", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expr_stack_incorrectcall_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t1", "type_t", ")", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *parse_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *cons; + cil_constrain_init(&cons); + cil_classpermset_init(&cons->classpermset); + cil_fill_classpermset(parse_current->next->cl_head, cons->classpermset); + + int rc = cil_gen_expr_stack(parse_current->next->next->cl_head->next->next, CIL_MLSCONSTRAIN, &cons->expr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roleallow(CuTest *tc) { + char *line[] = {"(", "roleallow", "staff_r", "sysadm_r", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_roleallow(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertStrEquals(tc, ((struct cil_roleallow*)test_ast_node->data)->src_str, test_current->next->data); + CuAssertStrEquals(tc, ((struct cil_roleallow*)test_ast_node->data)->tgt_str, test_current->next->next->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_ROLEALLOW); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_roleallow_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_roleallow(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roleallow_currnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_roleallow(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roleallow_astnull_neg(CuTest *tc) { + char *line[] = {"(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_roleallow(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roleallow_srcnull_neg(CuTest *tc) { + char *line[] = {"(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roleallow(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roleallow_tgtnull_neg(CuTest *tc) { + char *line[] = {"(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roleallow(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roleallow_extra_neg(CuTest *tc) { + char *line[] = {"(", "roleallow", "foo", "bar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roleallow(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_rolebounds(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_gen_rolebounds_norole1_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_rolebounds_role1_inparens_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", "(", "role1", ")", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_rolebounds_norole2_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_rolebounds_role2_inparens_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", "(", "role2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_rolebounds_extra_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", "role2", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_rolebounds_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_rolebounds_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_rolebounds_astnull_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_rolebounds(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} + +void test_cil_gen_avrule(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertStrEquals(tc, ((struct cil_avrule*)test_ast_node->data)->src_str, test_current->next->data); + CuAssertStrEquals(tc, ((struct cil_avrule*)test_ast_node->data)->tgt_str, test_current->next->next->data); + CuAssertStrEquals(tc, ((struct cil_avrule*)test_ast_node->data)->classpermset->class_str, test_current->next->next->next->cl_head->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_AVRULE); + CuAssertPtrNotNull(tc, ((struct cil_avrule*)test_ast_node->data)->classpermset->permset->perms_list_str); + + struct cil_list_item *test_list = ((struct cil_avrule*)test_ast_node->data)->classpermset->permset->perms_list_str->head; + test_current = test_current->next->next->next->cl_head->next->cl_head; + + while(test_list != NULL) { + CuAssertIntEquals(tc, test_list->flavor, CIL_AST_STR); + CuAssertStrEquals(tc, test_list->data, test_current->data ); + test_list = test_list->next; + test_current = test_current->next; + } +} + +void test_cil_gen_avrule_permset(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "permset", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_avrule_permset_anon(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_avrule_extra_neg(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "permset", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_sourceparens(CuTest *tc) { + char *line[] = {"(", "allow", "(", "test", ")", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_sourceemptyparen_neg(CuTest *tc) { + char *line[] = {"(", "allow", "(", ")", "bar", "file", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_targetparens(CuTest *tc) { + char *line[] = {"(", "allow", "test", "(", "foo", ")", "bar", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_targetemptyparen_neg(CuTest *tc) { + char *line[] = {"(", "allow", "bar", "(", ")", "file", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_astnull_neg(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "bar", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_sourcedomainnull_neg(CuTest *tc) { + char *line[] = {"(", "allow", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_targetdomainnull_neg(CuTest *tc) { + char *line[] = {"(", "allow", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_objectclassnull_neg(CuTest *tc) { + char *line[] = {"(", "allow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_permsnull_neg(CuTest *tc) { + char *line[] = {"(", "allow", "foo", "bar", "(", "baz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_avrule_twolists_neg(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "bar", "(", "write", ")", "(", "read", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + int rc = cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_transition(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->src_str, test_tree->root->cl_head->cl_head->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->tgt_str, test_tree->root->cl_head->cl_head->next->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->obj_str, test_tree->root->cl_head->cl_head->next->next->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->result_str, test_tree->root->cl_head->cl_head->next->next->next->next->data); + CuAssertIntEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->rule_kind, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TYPE_RULE); +} + +void test_cil_gen_type_rule_transition_currnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_type_rule(NULL, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_transition_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_transition_srcnull_neg(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_transition_tgtnull_neg(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_transition_objnull_neg(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_transition_resultnull_neg(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_transition_extra_neg(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_change(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->src_str, test_tree->root->cl_head->cl_head->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->tgt_str, test_tree->root->cl_head->cl_head->next->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->obj_str, test_tree->root->cl_head->cl_head->next->next->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->result_str, test_tree->root->cl_head->cl_head->next->next->next->next->data); + CuAssertIntEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->rule_kind, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TYPE_RULE); +} + +void test_cil_gen_type_rule_change_currnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_type_rule(NULL, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_change_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_change_srcnull_neg(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_change_tgtnull_neg(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_change_objnull_neg(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_change_resultnull_neg(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_change_extra_neg(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_CHANGE); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_member(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->src_str, test_tree->root->cl_head->cl_head->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->tgt_str, test_tree->root->cl_head->cl_head->next->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->obj_str, test_tree->root->cl_head->cl_head->next->next->next->data); + CuAssertStrEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->result_str, test_tree->root->cl_head->cl_head->next->next->next->next->data); + CuAssertIntEquals(tc, ((struct cil_type_rule*)test_ast_node->data)->rule_kind, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_TYPE_RULE); +} + +void test_cil_gen_type_rule_member_currnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_type_rule(NULL, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_member_astnull_neg(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_member_srcnull_neg(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_member_tgtnull_neg(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_member_objnull_neg(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_member_resultnull_neg(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + test_tree->root->cl_head->cl_head->next->next->next->next = NULL; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_type_rule_member_extra_neg(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_MEMBER); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_user(CuTest *tc) { + char *line[] = {"(", "user", "sysadm", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_user(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, CIL_USER, test_ast_node->flavor); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertPtrEquals(tc, test_ast_node, ((struct cil_symtab_datum*)test_ast_node->data)->node); + CuAssertStrEquals(tc, test_tree->root->cl_head->cl_head->next->data, ((struct cil_symtab_datum*)test_ast_node->data)->name); +} + +void test_cil_gen_user_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "user", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_user(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_user_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_user(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_user_astnull_neg(CuTest *tc) { + char *line[] = {"(", "user", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_user(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_user_nouser_neg(CuTest *tc) { + char *line[] = {"(", "user", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_user(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_user_xsinfo_neg(CuTest *tc) { + char *line[] = {"(", "user", "sysadm", "xsinfo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_user(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel(CuTest *tc) { + char *line[] = {"(", "userlevel", "user_u", "lvl_l", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_userlevel_anon_level(CuTest *tc) { + char *line[] = {"(", "userlevel", "user_u", "(", "s0", "(", "c0", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_userlevel_anon_level_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "user_u", "(", "s0", "(", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_usernull_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_userrange_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "(", "user", ")", "level", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_levelnull_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "user_u", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_levelrangeempty_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "user_u", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_extra_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "user_u", "level", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "user", "level", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userlevel_astnull_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "user", "level", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_userlevel(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_named(CuTest *tc) { + char *line[] = {"(", "userrange", "user_u", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_userrange_anon(CuTest *tc) { + char *line[] = {"(", "userrange", "user_u", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_userrange_usernull_neg(CuTest *tc) { + char *line[] = {"(", "userrange", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_anonuser_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "(", "user_u", ")", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_rangenamenull_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "user_u", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_anonrangeinvalid_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "user_u", "(", "low", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_anonrangeempty_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "user_u", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_extra_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "user_u", "(", "low", "high", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "user", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrange_astnull_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "user", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_userrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensitivity(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sensitivity(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_ast_node->data); + CuAssertIntEquals(tc, test_ast_node->flavor, CIL_SENS); + +} + +void test_cil_gen_sensitivity_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_sensitivity(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensitivity_currnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_sensitivity(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensitivity_astnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_sensitivity(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensitivity_sensnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensitivity(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensitivity_senslist_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "(", "s0", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensitivity(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensitivity_extra_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensitivity(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_sensalias_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias_currnull_neg(CuTest *tc) { + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_sensalias(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias_astnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init (&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias_sensnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias_senslist_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "(", "s0", "s1", ")", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias_aliasnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias_aliaslist_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "(", "alias", "alias2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_sensalias_extra_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_category(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_category(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_category_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_category(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_category_astnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_category(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_category_currnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_category(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_category_catnull_neg(CuTest *tc){ + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_category(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_category_catlist_neg(CuTest *tc){ + char *line[] = {"(", "category", "(", "c0", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_category(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_category_extra_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_category(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_catset_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_currnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_astnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_namenull_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_setnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_namelist_neg(CuTest *tc) { //This should fail before gen_node call - additional syntax checks are needed + char *line[] = {"(", "categoryset", "(", "somecats", ")", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_extra_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_notset_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "blah", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +// TODO: This doesn't actually test failure of gen_node +void test_cil_gen_catset_nodefail_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", "(", "c3", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catset_settolistfail_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catset(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catalias(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_catalias_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_catalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catalias_currnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catalias(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catalias_astnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_catalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catalias_catnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catalias_aliasnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root->cl_head->cl_head->next->next = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catalias_extra_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", "(", "c0", "c1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_catrange_noname_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange_norange_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange_emptyrange_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange_extrarange_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", "(", "c0", "c1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catrange(test_db, NULL, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange_astnull_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", "(", "c0", "c1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catrange_extra_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", "(", "c0", "c1", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletype(CuTest *tc) { + char *line[] = {"(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_roletype_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletype_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletype_astnull_neg(CuTest *tc) { + char *line[] = {"(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + + +void test_cil_gen_roletype_empty_neg(CuTest *tc) { + char *line[] = {"(", "roletype", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletype_rolelist_neg(CuTest *tc) { + char *line[] = {"(", "roletype", "(", "admin_r", ")", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +// TODO +// Not sure this is actually testing roletype +// I think this will just test that type is null +void test_cil_gen_roletype_roletype_sublist_neg(CuTest *tc) { + char *line[] = {"(", "(", "roletype", "admin_r", ")", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_roletype_typelist_neg(CuTest *tc) { + char *line[] = {"(", "roletype", "admin_r", "(", "admin_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_roletype(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrole(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_userrole_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrole_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrole_astnull_neg(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrole_empty_neg(CuTest *tc) { + char *line[] = {"(", "userrole", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrole_userlist_neg(CuTest *tc) { + char *line[] = {"(", "userrole", "(", "staff_u", ")", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + + +//TODO: see above +void test_cil_gen_userrole_userrole_sublist_neg(CuTest *tc) { + char *line[] = {"(", "(", "userrole", "staff_u", ")", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_userrole_rolelist_neg(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "(", "staff_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classcommon(CuTest *tc) { + char *line[] = {"(", "classcommon", "file", "file", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + char *test_key = test_tree->root->cl_head->cl_head->next->data; + struct cil_class *test_cls; + cil_class_init(&test_cls); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_insert(&test_db->symtab[CIL_SYM_CLASSES], (hashtab_key_t)test_key, (struct cil_symtab_datum*)test_cls, test_ast_node); + + test_ast_node->data = test_cls; + test_ast_node->flavor = CIL_CLASS; + + int rc = cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_classcommon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "classcommon", "file", "file", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classcommon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classcommon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "classcommon", "file", "file", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classcommon_missingclassname_neg(CuTest *tc) { + char *line[] = {"(", "classcommon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classcommon_noperms_neg(CuTest *tc) { + char *line[] = {"(", "classcommon", "file", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + char *test_key = test_tree->root->cl_head->cl_head->next->data; + struct cil_class *test_cls; + cil_class_init(&test_cls); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_insert(&test_db->symtab[CIL_SYM_CLASSES], (hashtab_key_t)test_key, (struct cil_symtab_datum*)test_cls, test_ast_node); + + test_ast_node->data = test_cls; + test_ast_node->flavor = CIL_CLASS; + + int rc = cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_classcommon_extraperms_neg(CuTest *tc) { + char *line[] = {"(", "classcommon", "file", "file", "file", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + char *test_key = test_tree->root->cl_head->cl_head->next->data; + struct cil_class *test_cls; + cil_class_init(&test_cls); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_insert(&test_db->symtab[CIL_SYM_CLASSES], (hashtab_key_t)test_key, (struct cil_symtab_datum*)test_cls, test_ast_node); + + test_ast_node->data = test_cls; + test_ast_node->flavor = CIL_CLASS; + + int rc = cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catorder(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_catorder_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db = NULL; + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + int rc = cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catorder_currnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catorder_astnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node = NULL; + + int rc = cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catorder_missingcats_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catorder_nosublist_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "c0", "c255", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_catorder_nestedcat_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "(", "c255", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_dominance(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_dominance(test_db, test_tree->root->cl_head->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_dominance_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_dominance(test_db, test_tree->root->cl_head->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_dominance_currnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_dominance(test_db, test_tree->root->cl_head->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_dominance_astnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_dominance(test_db, test_tree->root->cl_head->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_dominance_nosensitivities_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_dominance(test_db, test_tree->root->cl_head->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_dominance_nosublist_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "s0", "s2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_dominance(test_db, test_tree->root->cl_head->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_senscat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->next->next->next->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_senscat_nosublist(CuTest *tc) { + char *line[] = {"(", "sensitivitycategory", "s1", "c0", "c255", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_senscat_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->next->next->next->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_senscat_currnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->next->next->next->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_senscat_astnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->next->next->next->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_senscat_nosensitivities_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->next->next->next->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_senscat_sublist_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "(", "c255", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->next->next->next->next->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_senscat_nocat_neg(CuTest *tc) { + char *line[] = {"(", "sensitivitycategory", "s1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_senscat(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_level(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_level *test_level; + cil_level_init(&test_level); + + int rc = cil_fill_level(test_tree->root->cl_head->next->next->cl_head->next->next->cl_head, test_level); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_level_sensnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_level *test_level; + cil_level_init(&test_level); + + int rc = cil_fill_level(test_tree->root->cl_head->next->next->cl_head->next->next, test_level); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_level_levelnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_level *test_level = NULL; + + int rc = cil_fill_level(test_tree->root->cl_head->next->next->cl_head->next->next->cl_head, test_level); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_level_nocat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_level *test_level; + cil_level_init(&test_level); + + int rc = cil_fill_level(test_tree->root->cl_head->next->next->cl_head->next->next->cl_head, test_level); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_level_emptycat_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_level *test_level; + cil_level_init(&test_level); + + int rc = cil_fill_level(test_tree->root->cl_head->next->next->cl_head->next->next->cl_head, test_level); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_level_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "level", "(", "low", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_emptysensparens_neg(CuTest *tc) { + char *line[] = {"(", "level", "low", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_extra_neg(CuTest *tc) { + char *line[] = {"(", "level", "low", "(", "s0", "(", "c0", ")", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_emptycat_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_noname_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_nosens_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_currnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_level_astnull_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_level(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_levelrange_rangeinvalid_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", "(", "low", "high", "extra", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange_namenull_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange_rangenull_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange_rangeempty_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange_extra_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", "(", "low", "high", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_levelrange_astnull_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_levelrange(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_constrain_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "dne", "l1", "l2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_classset_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_classset_noclass_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_classset_noperm_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_permset_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_permset_noclass_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_permset_noperm_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_expression_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_constrain_astnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "node_lo_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_context_unnamedlvl(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "node_lo_t", "(", "(", "s0", ")", "(", "s0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_context_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "node_lo_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context = NULL; + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context_nouser_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context_norole_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context_notype_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context_nolowlvl_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "type_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context_nohighlvl_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "type_t", "(", "low", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context_unnamedlvl_nocontextlow_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "type_t", "(", "s0", "(", ")", ")", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_context_unnamedlvl_nocontexthigh_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "type_t", "low", "(", "s0", "(", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_context *test_context; + cil_context_init(&test_context); + + int rc = cil_fill_context(test_tree->root->cl_head->cl_head->next->next->cl_head, test_context); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_context_notinparens_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_extralevel_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", "extra", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_emptycontext_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_extra_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", "(", "extra", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_doubleparen_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "(", "system_u", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_norole_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_roleinparens_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "(", "role_r", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_notype_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "role_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_typeinparens_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "role_r", "(", "type_t", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_nolevels_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "role_r", "type_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_nosecondlevel_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "role_r", "type_t", "(", "low", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_noname_neg(CuTest *tc) { + char *line[] = {"(", "context", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_nouser_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "node_lo_t", "(", "s0", ")", "(", "s0", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_context_astnull_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "system_u", "object_r", "node_lo_t", "(", "s0", ")", "(", "s0", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_dir(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "dir", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_file(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_char(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "char", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_block(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "block", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_socket(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "socket", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_pipe(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "pipe", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_symlink(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "symlink", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_any(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "any", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "dne", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_anon_context(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_filecon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_str1null_neg(CuTest *tc) { + char *line[] = {"(", "filecon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_str1_inparens_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "(", "root", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_str2null_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_str2_inparens_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "(", "path", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_classnull_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_class_inparens_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "(", "file", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_contextnull_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_context_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", "(", "system_u", "object_r", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_filecon_extra_neg(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", "context", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_filecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_udp(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "80", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_portcon_tcp(CuTest *tc) { + char *line[] = {"(", "portcon", "tcp", "80", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_portcon_unknownprotocol_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "unknown", "80", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_anon_context(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "80", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_portcon_portrange(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "(", "25", "75", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_portcon_portrange_one_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "(", "0", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_portrange_morethanone_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "(", "0", "1", "2", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_singleport_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "foo", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_lowport_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "(", "foo", "90", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_highport_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "(", "80", "foo", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "(", "0", "1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "(", "0", "1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_str1null_neg(CuTest *tc) { + char *line[] = {"(", "portcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_str1parens_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "(", "80", ")", "port", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_portnull_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_contextnull_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "port", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_context_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "80", "(", "system_u", "object_r", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_portcon_extra_neg(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "80", "con", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_portcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_ipaddr(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "192.168.1.1", ")", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_nodecon *nodecon; + cil_nodecon_init(&nodecon); + cil_ipaddr_init(&nodecon->addr); + + int rc = cil_fill_ipaddr(test_tree->root->cl_head->cl_head->next->cl_head, nodecon->addr); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_fill_ipaddr_addrnodenull_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "192.168.1.1", ")", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_nodecon *nodecon; + cil_nodecon_init(&nodecon); + cil_ipaddr_init(&nodecon->addr); + + int rc = cil_fill_ipaddr(NULL, nodecon->addr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_ipaddr_addrnull_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "192.168.1.1", ")", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_nodecon *nodecon; + cil_nodecon_init(&nodecon); + nodecon->addr = NULL; + + int rc = cil_fill_ipaddr(test_tree->root->cl_head->cl_head->next->cl_head, nodecon->addr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_ipaddr_addrinparens_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "(", "192.168.1.1", ")", ")", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_nodecon *nodecon; + cil_nodecon_init(&nodecon); + cil_ipaddr_init(&nodecon->addr); + + int rc = cil_fill_ipaddr(test_tree->root->cl_head->cl_head->next->cl_head, nodecon->addr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_fill_ipaddr_extra_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "192.168.1.1", "extra", ")", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_nodecon *nodecon; + cil_nodecon_init(&nodecon); + cil_ipaddr_init(&nodecon->addr); + + int rc = cil_fill_ipaddr(test_tree->root->cl_head->cl_head->next->cl_head, nodecon->addr); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_nodecon_anon_context(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_nodecon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "con", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "con", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_ipnull_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_ipanon(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "192.168.1.1", ")", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_nodecon_ipanon_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "192.1.1", ")", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_netmasknull_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_netmaskanon(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "(", "255.255.255.4", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_nodecon_netmaskanon_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "(", "str0", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_contextnull_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_context_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "(", "system_u", "object_r", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_nodecon_extra_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "(", "system_u", "object_r", "type_t", "(", "low", "high", ")", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_genfscon_anon_context(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_genfscon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_typenull_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_typeparens_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "(", "type", ")", "path", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_pathnull_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_pathparens_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "(", "path", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_contextnull_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_context_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", "(", "system_u", "object_r", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_genfscon_extra_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", "con", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_genfscon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_netifcon_nested(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_netifcon_nested_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "(", "eth1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_nested_emptysecondlist_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_extra_nested_secondlist_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", "extra", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_nested_missingobjects_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth1", + "(", "system_u", ")", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_nested_secondnested_missingobjects_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "system_u", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_ethmissing_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_interfacemissing_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_netifcon_packetmissing_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", "if_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_pirqcon_pirqnotint_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "notint", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_nopirq_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_pirqrange_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "(", "1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_anoncontext_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", "(", "con", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_extra_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", "con", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pirqcon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_pirqcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_iomemcon_iomemrange(CuTest *tc) { + char *line[] = {"(", "iomemcon", "(", "1", "2", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_iomemcon_iomemrange_firstnotint_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "(", "foo", "2", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_iomemrange_secondnotint_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "(", "1", "foo", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_iomemrange_empty_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "(", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_iomemrange_singleiomem_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "(", "1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_iomemrange_morethantwoiomem_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "(", "1", "2", "3", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_iomemnotint_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "notint", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_noiomem_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_anoncontext_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", "(", "con", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_extra_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", "con", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_iomemcon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_iomemcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_ioportcon_ioportrange(CuTest *tc) { + char *line[] = {"(", "ioportcon", "(", "1", "2", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_ioportcon_ioportrange_firstnotint_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "(", "foo", "2", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_ioportrange_secondnotint_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "(", "1", "foo", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_ioportrange_empty_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "(", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_ioportrange_singleioport_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "(", "1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_ioportrange_morethantwoioport_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "(", "1", "2", "3", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_ioportnotint_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "notint", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_noioport_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_anoncontext_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", "(", "con", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_extra_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", "con", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ioportcon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_ioportcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_pcidevicecon_pcidevicenotint_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "notint", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_nopcidevice_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_pcidevicerange_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "(", "1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_anoncontext_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", "(", "con", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_extra_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", "con", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_pcidevicecon_astnull_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_pcidevicecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_anoncontext(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_fsuse_anoncontext_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "(", "system_u", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_xattr(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_fsuse_task(CuTest *tc) { + char *line[] = {"(", "fsuse", "task", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_fsuse_transition(CuTest *tc) { + char *line[] = {"(", "fsuse", "trans", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_fsuse_invalidtype_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "foo", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_notype_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_typeinparens_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "(", "xattr", ")", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_nofilesystem_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_filesysteminparens_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "(", "ext3", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_emptyconparens_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_extra_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "con", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_fsuse_astnull_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_fsuse(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_noparams(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", ")", "(", "type", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_type(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "type", "a", ")", ")", "(", "type", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_role(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "role", "a", ")", ")", "(", "role", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_user(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "user", "a", ")", ")", "(", "user", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_sensitivity(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "sensitivity", "a", ")", ")", "(", "sensitivity", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_category(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "category", "a", ")", ")", "(", "category", "b", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_catset(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "categoryset", "a", ")", ")", "(", "categoryset", "b", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_level(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "level", "a", ")", ")", "(", "level", "b", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_class(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "class", "a", ")", ")", "(", "class", "b", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_classmap(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "classmap", "a", ")", ")", "(", "classmap", "b", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_permset(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "permissionset", "a", ")", ")", + "(", "allow", "foo", "bar", "baz", "a", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_duplicate(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "class", "a",")", "(", "class", "x", ")", ")", "(", "class", "b", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_macro_duplicate_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "class", "a",")", "(", "class", "a", ")", ")", "(", "class", "b", "(", "read," ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_unknown_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "foo", "a", ")", ")", "(", "foo", "b", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "foo", "a", ")", ")", "(", "foo", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_astnull_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "foo", "a", ")", ")", "(", "foo", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node = NULL; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_unnamed_neg(CuTest *tc) { + char *line[] = {"(", "macro", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_noparam_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_nosecondparam_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "foo", "a", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_noparam_name_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "type", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_emptyparam_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", ")", ")", "(", "foo", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_macro_paramcontainsperiod_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "type", "a.", ")", ")", "(", "type", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_macro(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_call(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_call_noargs(CuTest *tc) { + char *line[] = {"(", "call", "mm", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_call_anon(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_call_empty_call_neg(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_call_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_call_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_call_astnull_neg(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_call_name_inparens_neg(CuTest *tc) { + char *line[] = {"(", "call", "(", "mm", ")", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_call_noname_neg(CuTest *tc) { + char *line[] = {"(", "call", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_optional(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_optional_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_optional_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_optional_astnull_neg(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_optional_unnamed_neg(CuTest *tc) { + char *line[] = {"(", "optional", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_optional_extra_neg(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_optional_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "optional", "(", "opt", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_optional_emptyoptional(CuTest *tc) { + char *line[] = {"(", "optional", "opt", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_optional_norule_neg(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_policycap(CuTest *tc) { + char *line[] = {"(", "policycap", "open_perms", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_policycap_noname_neg(CuTest *tc) { + char *line[] = {"(", "policycap", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_policycap_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "policycap", "(", "pol", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_policycap_extra_neg(CuTest *tc) { + char *line[] = {"(", "policycap", "pol", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_policycap_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "policycap", "pol", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_policycap_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_policycap_astnull_neg(CuTest *tc) { + char *line[] = {"(", "policycap", "pol", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_policycap_neg(CuTest *tc) { + char *line[] = {"(", "policycap", "pol", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_policycap(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_ipv4(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_ipaddr_ipv4_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", ".168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_ipv6(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_gen_ipaddr_ipv6_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "2001:0db8:85a3:0000:0000:8a2e:0370:::7334", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_noname_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_nameinparens_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "(", "ip", ")", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_noip_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_ipinparens_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "(", "192.168.1.1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_extra_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db = NULL; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_currnull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_gen_ipaddr_astnull_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +/* + cil_build_ast test cases +*/ + +void test_cil_build_ast(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_build_ast(test_db, test_tree->root, test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_dbnull_neg(CuTest *tc) { + char *line[] = {"(", "test", "\"qstring\"", ")", ";comment", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *null_db = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_build_ast(null_db, test_tree->root, test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_astnull_neg(CuTest *tc) { + char *line[] = {"(", "test", "\"qstring\"", ")", ";comment", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_db->ast->root = NULL; + + int rc = cil_build_ast(test_db, test_tree->root, test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_suberr_neg(CuTest *tc) { + char *line[] = {"(", "block", "test", "(", "block", "(", "type", "log", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = cil_build_ast(test_db, test_tree->root, test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_treenull_neg(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "bar", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + test_tree->root = NULL; + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_db->ast->root = NULL; + + int rc = cil_build_ast(test_db, test_tree->root, test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_block(CuTest *tc) { + char *line[] = {"(", "block", "test", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_block_neg(CuTest *tc) { + char *line[] = {"(", "block", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); + +} + +void test_cil_build_ast_node_helper_blockinherit(CuTest *tc) { + char *line[] = {"(", "blockinherit", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_blockinherit_neg(CuTest *tc) { + char *line[] = {"(", "blockinherit", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); + +} + +void test_cil_build_ast_node_helper_permset(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, CIL_TREE_SKIP_NEXT, finished); +} + +void test_cil_build_ast_node_helper_permset_neg(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); + +} + +void test_cil_build_ast_node_helper_in(CuTest *tc) { + char *line[] = {"(", "in", "foo", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_in_neg(CuTest *tc) { + char *line[] = {"(", "in", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_class(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_class_neg(CuTest *tc) { + char *line[] = {"(", "class", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_classpermset(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", "(", "read", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, CIL_TREE_SKIP_NEXT, finished); +} + +void test_cil_build_ast_node_helper_classpermset_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); + +} + +void test_cil_build_ast_node_helper_classmap(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_classmap_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_classmapping(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", "char_w", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_classmapping_neg(CuTest *tc) { + char *line[] = {"(", "classmapping", "files", "read", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_common(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_common_neg(CuTest *tc) { + char *line[] = {"(", "common", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_sid(CuTest *tc) { + char *line[] = {"(", "sid", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_sid_neg(CuTest *tc) { + char *line[] = {"(", "sid", "(", "blah", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_sidcontext(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "(", "blah", "blah", "blah", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_sidcontext_neg(CuTest *tc) { + char *line[] = {"(", "sidcontext", "(", "blah", "blah", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_user(CuTest *tc) { + char *line[] = {"(", "user", "jimmypage", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_user_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo", "bar", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_userlevel(CuTest *tc) { + char *line[] = {"(", "userlevel", "johnpauljones", "level", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_userlevel_neg(CuTest *tc) { + char *line[] = {"(", "userlevel", "johnpauljones", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_userrange(CuTest *tc) { + char *line[] = {"(", "userrange", "johnpauljones", "range", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_userrange_neg(CuTest *tc) { + char *line[] = {"(", "userrange", "johnpauljones", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type(CuTest *tc) { + char *line[] = {"(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type_neg(CuTest *tc) { + char *line[] = {"(", "type", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_attribute(CuTest *tc) { + char *line[] = {"(", "typeattribute", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_attribute_neg(CuTest *tc) { + char *line[] = {"(", "typeattribute", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typebounds(CuTest *tc) { + char *line[] = {"(", "typebounds", "foo", "bar", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typebounds_neg(CuTest *tc) { + char *line[] = {"(", "typebounds", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typepermissive(CuTest *tc) { + char *line[] = {"(", "typepermissive", "foo", ")", NULL}; + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typepermissive_neg(CuTest *tc) { + char *line[] = {"(", "typepermissive", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_nametypetransition(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_nametypetransition_neg(CuTest *tc) { + char *line[] = {"(", "nametypetransition", "str", "foo", "bar", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_rangetransition(CuTest *tc) { + char *line[] = {"(", "rangetransition", "type_a", "type_b", "class", "(", "low_l", "high_l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_rangetransition_neg(CuTest *tc) { + char *line[] = {"(", "rangetransition", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_boolif(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_boolif_neg(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "*&", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_condblock_true(CuTest *tc) { + char *line[] = {"(", "true", "(", "allow", "foo", "bar", "baz", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_condblock_true_neg(CuTest *tc) { + char *line[] = {"(", "true", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_condblock_false(CuTest *tc) { + char *line[] = {"(", "false", "(", "allow", "foo", "bar", "baz", "(", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_condblock_false_neg(CuTest *tc) { + char *line[] = {"(", "false", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_tunif(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_tunif_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "*&", "foo", "bar", ")", + "(", "allow", "foo", "bar", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typealias(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typealias_notype_neg(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typeattribute(CuTest *tc) +{ + char *line[] = {"(", "typeattribute", "type", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typeattribute_neg(CuTest *tc) +{ + char *line[] = {"(", "typeattribute", ".fail.type", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_typeattributeset(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "filetypes", "(", "and", "test_t", "test2_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_typeattributeset_neg(CuTest *tc) { + char *line[] = {"(", "typeattributeset", "files", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_userbounds(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_userbounds_neg(CuTest *tc) { + char *line[] = {"(", "userbounds", "user1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_role(CuTest *tc) { + char *line[] = {"(", "role", "test_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_role_neg(CuTest *tc) { + char *line[] = {"(", "role", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_roletransition(CuTest *tc) { + char *line[] = {"(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_roletransition_neg(CuTest *tc) { + char *line[] = {"(", "roletransition", "foo_r", "bar_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_roleallow(CuTest *tc) { + char *line[] = {"(", "roleallow", "staff_r", "sysadm_r", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_roleallow_neg(CuTest *tc) { + char *line[] = {"(", "roleallow", "staff_r", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_rolebounds(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_rolebounds_neg(CuTest *tc) { + char *line[] = {"(", "rolebounds", "role1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_avrule_allow(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_avrule_allow_neg(CuTest *tc) { + char *line[] = {"(", "allow", "foo", "bar", "(", "read", "write", ")", "blah", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_avrule_auditallow(CuTest *tc) { + char *line[] = {"(", "auditallow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_avrule_auditallow_neg(CuTest *tc) { + char *line[] = {"(", "auditallow", "foo", "bar", "(", "read", "write", ")", "blah", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_avrule_dontaudit(CuTest *tc) { + char *line[] = {"(", "dontaudit", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_avrule_dontaudit_neg(CuTest *tc) { + char *line[] = {"(", "dontaudit", "foo", "bar", "(", "read", "write", ")", "blah", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_avrule_neverallow(CuTest *tc) { + char *line[] = {"(", "neverallow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_avrule_neverallow_neg(CuTest *tc) { + char *line[] = {"(", "neverallow", "foo", "bar", "(", "read", "write", ")", "blah", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type_rule_transition(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type_rule_transition_neg(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type_rule_change(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type_rule_change_neg(CuTest *tc) { + char *line[] = {"(", "typechange", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type_rule_member(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_type_rule_member_neg(CuTest *tc) { + char *line[] = {"(", "typemember", "foo", "bar", "file", "foobar", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_bool(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_bool_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_bool_tunable(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_bool_tunable_neg(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_sensitivity(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_sensitivity_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_sensalias(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_sensalias_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_category(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_category_neg(CuTest *tc) { + char *line[] = {"(", "category", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_catset(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_catset_neg(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_catorder(CuTest *tc) { + char *line[] = {"(", "categoryorder", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_catorder_neg(CuTest *tc) { + char *line[] = {"(", "categoryorder", "c0", "c1", "c2", "extra", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_catalias(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_catalias_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "range", "(", "c0", "c1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_catrange(CuTest *tc) { + char *line[] = {"(", "categoryrange", "range", "(", "c0", "c1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 1, finished); +} + +void test_cil_build_ast_node_helper_catrange_neg(CuTest *tc) { + char *line[] = {"(", "categoryrange", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_build_ast_node_helper_roletype(CuTest *tc) { + char *line[] = {"(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_roletype_neg(CuTest *tc) { + char *line[] = {"(", "roletype", "(", "admin_r", ")", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_userrole(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_userrole_neg(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "(", "staff_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_classcommon(CuTest *tc) { + char *line[] = {"(", "classcommon", "foo", "foo", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_classcommon_neg(CuTest *tc) { + char *line[] = {"(", "classcommon", "staff_u", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_dominance(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->next->next->next->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_dominance_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->next->next->next->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_senscat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->next->next->next->next->next->next->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_senscat_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->next->next->next->next->next->next->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_level(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->next->next->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_level_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "low", "(", "s0", "(", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->next->next->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_levelrange(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_levelrange_neg(CuTest *tc) { + char *line[] = {"(", "levelrange", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_constrain(CuTest *tc) { + char *line[] = {"(", "constrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "r2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_constrain_neg(CuTest *tc) { + char *line[] = {"(", "constrain", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_mlsconstrain(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_mlsconstrain_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_context(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", "node_lo_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_context_neg(CuTest *tc) { + char *line[] = {"(", "context", "localhost_node_label", "(", "system_u", "object_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_filecon(CuTest *tc) { + char *line[] = {"(", "filecon", "root", "path", "file", "context", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_filecon_neg(CuTest *tc) { + char *line[] = {"(", "filecon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_portcon(CuTest *tc) { + char *line[] = {"(", "portcon", "udp", "25", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_portcon_neg(CuTest *tc) { + char *line[] = {"(", "portcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_nodecon(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_nodecon_neg(CuTest *tc) { + char *line[] = {"(", "nodecon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_genfscon(CuTest *tc) { + char *line[] = {"(", "genfscon", "type", "path", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_genfscon_neg(CuTest *tc) { + char *line[] = {"(", "genfscon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_netifcon(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_netifcon_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_pirqcon(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_pirqcon_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_iomemcon(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_iomemcon_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_ioportcon(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_ioportcon_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_pcidevicecon(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_pcidevicecon_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_fsuse(CuTest *tc) { + char *line[] = {"(", "fsuse", "xattr", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_fsuse_neg(CuTest *tc) { + char *line[] = {"(", "fsuse", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_macro(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "type", "a", ")", ")", "(", "type", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_macro_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_macro_nested_macro_neg(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "type", "a", ")", ")", "(", "type", "b", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_macro *macro; + cil_macro_init(¯o); + + struct cil_tree_node *macronode; + cil_tree_node_init(¯onode); + macronode->data = macro; + macronode->flavor = CIL_MACRO; + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, macronode, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + + cil_db_destroy(&test_db); + cil_destroy_macro(macro); +} + +void test_cil_build_ast_node_helper_gen_macro_nested_tunif_neg(CuTest *tc) { + char *line[] = {"(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "allow", "foo", "bar", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_macro *macro; + cil_macro_init(¯o); + + struct cil_tree_node *macronode; + cil_tree_node_init(¯onode); + macronode->data = macro; + macronode->flavor = CIL_MACRO; + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, macronode, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + + cil_db_destroy(&test_db); + cil_destroy_macro(macro); +} + +void test_cil_build_ast_node_helper_gen_call(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_call_neg(CuTest *tc) { + char *line[] = {"(", "call", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_optional(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_optional_neg(CuTest *tc) { + char *line[] = {"(", "optional", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_policycap(CuTest *tc) { + char *line[] = {"(", "policycap", "open_perms", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 1); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_policycap_neg(CuTest *tc) { + char *line[] = {"(", "policycap", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_gen_ipaddr(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_node_helper_gen_ipaddr_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_node_helper_extraargsnull_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_args_build *extra_args = NULL; + + uint32_t finished = 0; + + int rc = __cil_build_ast_node_helper(test_tree->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_build_ast_last_child_helper(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_args_build *extra_args = gen_build_args(test_db->ast->root, test_db, NULL, NULL); + + int rc = __cil_build_ast_last_child_helper(test_tree->root->cl_head->cl_head, extra_args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_build_ast_last_child_helper_extraargsnull_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + int rc = __cil_build_ast_last_child_helper(test_tree->root->cl_head->cl_head, NULL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + diff --git a/kernel/libsepol/cil/test/unit/test_cil_build_ast.h b/kernel/libsepol/cil/test/unit/test_cil_build_ast.h new file mode 100644 index 00000000..d6974330 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_build_ast.h @@ -0,0 +1,1198 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_BUILD_AST_H_ +#define TEST_CIL_BUILD_AST_H_ + +#include "CuTest.h" + +void test_cil_parse_to_list(CuTest *); +void test_cil_parse_to_list_currnull_neg(CuTest *); +void test_cil_parse_to_list_listnull_neg(CuTest *); + +void test_cil_set_to_list(CuTest *); +void test_cil_set_to_list_tree_node_null_neg(CuTest *); +void test_cil_set_to_list_cl_head_null_neg(CuTest *); +void test_cil_set_to_list_listnull_neg(CuTest *); + +void test_cil_gen_block(CuTest *); +void test_cil_gen_block_justblock_neg(CuTest *); +void test_cil_gen_block_noname_neg(CuTest *); +void test_cil_gen_block_dbnull_neg(CuTest *); +void test_cil_gen_block_treenull_neg(CuTest *); +void test_cil_gen_block_nodenull_neg(CuTest *); +void test_cil_gen_block_nodeparentnull_neg(CuTest *); +void test_cil_destroy_block(CuTest *); + +void test_cil_gen_blockinherit(CuTest *); +void test_cil_gen_blockinherit_namelist_neg(CuTest *); +void test_cil_gen_blockinherit_namenull_neg(CuTest *); +void test_cil_gen_blockinherit_extra_neg(CuTest *); +void test_cil_gen_blockinherit_dbnull_neg(CuTest *); +void test_cil_gen_blockinherit_currnull_neg(CuTest *); +void test_cil_gen_blockinherit_astnull_neg(CuTest *); + +void test_cil_gen_perm(CuTest *); +void test_cil_gen_perm_noname_neg(CuTest *); +void test_cil_gen_perm_dbnull_neg(CuTest *); +void test_cil_gen_perm_currnull_neg(CuTest *); +void test_cil_gen_perm_astnull_neg(CuTest *); +void test_cil_gen_perm_nodenull_neg(CuTest *); + +void test_cil_gen_permset(CuTest *); +void test_cil_gen_permset_noname_neg(CuTest *); +void test_cil_gen_permset_nameinparens_neg(CuTest *); +void test_cil_gen_permset_noperms_neg(CuTest *); +void test_cil_gen_permset_emptyperms_neg(CuTest *); +void test_cil_gen_permset_extra_neg(CuTest *); +void test_cil_gen_permset_dbnull_neg(CuTest *); +void test_cil_gen_permset_currnull_neg(CuTest *); +void test_cil_gen_permset_astnull_neg(CuTest *); + +void test_cil_gen_perm_nodes(CuTest *); +void test_cil_gen_perm_nodes_failgen_neg(CuTest *); +void test_cil_gen_perm_nodes_inval_perm_neg(CuTest *); + +void test_cil_fill_permset(CuTest *); +void test_cil_fill_permset_sublist_neg(CuTest *); +void test_cil_fill_permset_startpermnull_neg(CuTest *); +void test_cil_fill_permset_permsetnull_neg(CuTest *); + +void test_cil_gen_in(CuTest *); +void test_cil_gen_in_blockstrnull_neg(CuTest *); +void test_cil_gen_in_extra_neg(CuTest *); +void test_cil_gen_in_dbnull_neg(CuTest *); +void test_cil_gen_in_currnull_neg(CuTest *); +void test_cil_gen_in_astnull_neg(CuTest *); + +void test_cil_gen_class(CuTest *); +void test_cil_gen_class_noname_neg(CuTest *); +void test_cil_gen_class_nodenull_neg(CuTest *); +void test_cil_gen_class_dbnull_neg(CuTest *); +void test_cil_gen_class_currnull_neg(CuTest *); +void test_cil_gen_class_noclass_neg(CuTest *); +void test_cil_gen_class_noclassname_neg(CuTest *); +void test_cil_gen_class_namesublist_neg(CuTest *); +void test_cil_gen_class_noperms(CuTest *); +void test_cil_gen_class_permsnotinlist_neg(CuTest *); +void test_cil_gen_class_extrapermlist_neg(CuTest *); +void test_cil_gen_class_listinlist_neg(CuTest *); + +void test_cil_fill_classpermset_anonperms(CuTest *); +void test_cil_fill_classpermset_anonperms_neg(CuTest *); +void test_cil_fill_classpermset_namedperms(CuTest *); +void test_cil_fill_classpermset_extra_neg(CuTest *); +void test_cil_fill_classpermset_emptypermslist_neg(CuTest *); +void test_cil_fill_classpermset_noperms_neg(CuTest *); +void test_cil_fill_classpermset_noclass_neg(CuTest *); +void test_cil_fill_classpermset_classnodenull_neg(CuTest *); +void test_cil_fill_classpermset_cpsnull_neg(CuTest *); + +void test_cil_gen_classpermset(CuTest *); +void test_cil_gen_classpermset_noname_neg(CuTest *); +void test_cil_gen_classpermset_nameinparens_neg(CuTest *); +void test_cil_gen_classpermset_noclass_neg(CuTest *); +void test_cil_gen_classpermset_noperms_neg(CuTest *); +void test_cil_gen_classpermset_emptyperms_neg(CuTest *); +void test_cil_gen_classpermset_extra_neg(CuTest *); +void test_cil_gen_classpermset_dbnull_neg(CuTest *); +void test_cil_gen_classpermset_currnull_neg(CuTest *); +void test_cil_gen_classpermset_astnull_neg(CuTest *); + +void test_cil_gen_classmap_perm(CuTest *); +void test_cil_gen_classmap_perm_dupeperm_neg(CuTest *); +void test_cil_gen_classmap_perm_dbnull_neg(CuTest *tc); +void test_cil_gen_classmap_perm_currnull_neg(CuTest *tc); +void test_cil_gen_classmap_perm_astnull_neg(CuTest *tc); + +void test_cil_gen_classmap(CuTest *); +void test_cil_gen_classmap_extra_neg(CuTest *); +void test_cil_gen_classmap_noname_neg(CuTest *); +void test_cil_gen_classmap_emptyperms_neg(CuTest *); +void test_cil_gen_classmap_dbnull_neg(CuTest *tc); +void test_cil_gen_classmap_currnull_neg(CuTest *tc); +void test_cil_gen_classmap_astnull_neg(CuTest *tc); + +void test_cil_gen_classmapping_anonpermset(CuTest *); +void test_cil_gen_classmapping_anonpermset_neg(CuTest *); +void test_cil_gen_classmapping_namedpermset(CuTest *); +void test_cil_gen_classmapping_noclassmapname_neg(CuTest *); +void test_cil_gen_classmapping_noclassmapperm_neg(CuTest *); +void test_cil_gen_classmapping_nopermissionsets_neg(CuTest *); +void test_cil_gen_classmapping_emptyperms_neg(CuTest *); +void test_cil_gen_classmapping_dbnull_neg(CuTest *tc); +void test_cil_gen_classmapping_currnull_neg(CuTest *tc); +void test_cil_gen_classmapping_astnull_neg(CuTest *tc); + +void test_cil_gen_common(CuTest *); +void test_cil_gen_common_dbnull_neg(CuTest *tc); +void test_cil_gen_common_currnull_neg(CuTest *tc); +void test_cil_gen_common_astnull_neg(CuTest *tc); +void test_cil_gen_common_noname_neg(CuTest *tc); +void test_cil_gen_common_twoperms_neg(CuTest *tc); +void test_cil_gen_common_permsublist_neg(CuTest *tc); +void test_cil_gen_common_noperms_neg(CuTest *tc); + +void test_cil_gen_sid(CuTest *); +void test_cil_gen_sid_noname_neg(CuTest *); +void test_cil_gen_sid_nameinparens_neg(CuTest *); +void test_cil_gen_sid_extra_neg(CuTest *); +void test_cil_gen_sid_dbnull_neg(CuTest *); +void test_cil_gen_sid_currnull_neg(CuTest *); +void test_cil_gen_sid_astnull_neg(CuTest *); + +void test_cil_gen_sidcontext(CuTest *); +void test_cil_gen_sidcontext_namedcontext(CuTest *); +void test_cil_gen_sidcontext_halfcontext_neg(CuTest *); +void test_cil_gen_sidcontext_noname_neg(CuTest *); +void test_cil_gen_sidcontext_empty_neg(CuTest *); +void test_cil_gen_sidcontext_nocontext_neg(CuTest *); +void test_cil_gen_sidcontext_dblname_neg(CuTest *); +void test_cil_gen_sidcontext_dbnull_neg(CuTest *); +void test_cil_gen_sidcontext_pcurrnull_neg(CuTest *); +void test_cil_gen_sidcontext_astnodenull_neg(CuTest *); + +void test_cil_gen_type(CuTest *); +void test_cil_gen_type_neg(CuTest *); +void test_cil_gen_type_dbnull_neg(CuTest *tc); +void test_cil_gen_type_currnull_neg(CuTest *tc); +void test_cil_gen_type_astnull_neg(CuTest *tc); +void test_cil_gen_type_extra_neg(CuTest *tc); + +void test_cil_gen_typeattribute(CuTest *); +void test_cil_gen_typeattribute_dbnull_neg(CuTest *tc); +void test_cil_gen_typeattribute_currnull_neg(CuTest *tc); +void test_cil_gen_typeattribute_astnull_neg(CuTest *tc); +void test_cil_gen_typeattribute_extra_neg(CuTest *tc); + +void test_cil_gen_typeattr(CuTest *); +void test_cil_gen_typeattr_dbnull_neg(CuTest *); +void test_cil_gen_typeattr_currnull_neg(CuTest *); +void test_cil_gen_typeattr_astnull_neg(CuTest *); +void test_cil_gen_typeattr_typenull_neg(CuTest *); +void test_cil_gen_typeattr_attrnull_neg(CuTest *); +void test_cil_gen_typeattr_attrlist_neg(CuTest *); +void test_cil_gen_typeattr_extra_neg(CuTest *); + +void test_cil_gen_typebounds(CuTest *); +void test_cil_gen_typebounds_notype1_neg(CuTest *); +void test_cil_gen_typebounds_type1inparens_neg(CuTest *); +void test_cil_gen_typebounds_notype2_neg(CuTest *); +void test_cil_gen_typebounds_type2inparens_neg(CuTest *); +void test_cil_gen_typebounds_extra_neg(CuTest *); +void test_cil_gen_typebounds_dbnull_neg(CuTest *); +void test_cil_gen_typebounds_currnull_neg(CuTest *); +void test_cil_gen_typebounds_astnull_neg(CuTest *); + +void test_cil_gen_typepermissive(CuTest *); +void test_cil_gen_typepermissive_noname_neg(CuTest *); +void test_cil_gen_typepermissive_typeinparens_neg(CuTest *); +void test_cil_gen_typepermissive_extra_neg(CuTest *); +void test_cil_gen_typepermissive_dbnull_neg(CuTest *); +void test_cil_gen_typepermissive_currnull_neg(CuTest *); +void test_cil_gen_typepermissive_astnull_neg(CuTest *); + +void test_cil_gen_nametypetransition(CuTest *); +void test_cil_gen_nametypetransition_nostr_neg(CuTest *); +void test_cil_gen_nametypetransition_strinparens_neg(CuTest *); +void test_cil_gen_nametypetransition_nosrc_neg(CuTest *); +void test_cil_gen_nametypetransition_srcinparens_neg(CuTest *); +void test_cil_gen_nametypetransition_notgt_neg(CuTest *); +void test_cil_gen_nametypetransition_tgtinparens_neg(CuTest *); +void test_cil_gen_nametypetransition_noclass_neg(CuTest *); +void test_cil_gen_nametypetransition_classinparens_neg(CuTest *); +void test_cil_gen_nametypetransition_nodest_neg(CuTest *); +void test_cil_gen_nametypetransition_destinparens_neg(CuTest *); +void test_cil_gen_nametypetransition_extra_neg(CuTest *); +void test_cil_gen_nametypetransition_dbnull_neg(CuTest *); +void test_cil_gen_nametypetransition_currnull_neg(CuTest *); +void test_cil_gen_nametypetransition_astnull_neg(CuTest *); + +void test_cil_gen_rangetransition(CuTest *); +void test_cil_gen_rangetransition_namedtransition(CuTest *); +void test_cil_gen_rangetransition_anon_low_l(CuTest *); +void test_cil_gen_rangetransition_anon_low_l_neg(CuTest *); +void test_cil_gen_rangetransition_anon_high_l(CuTest *); +void test_cil_gen_rangetransition_anon_high_l_neg(CuTest *); +void test_cil_gen_rangetransition_dbnull_neg(CuTest *); +void test_cil_gen_rangetransition_currnull_neg(CuTest *); +void test_cil_gen_rangetransition_astnull_neg(CuTest *); +void test_cil_gen_rangetransition_nofirsttype_neg(CuTest *); +void test_cil_gen_rangetransition_firsttype_inparens_neg(CuTest *); +void test_cil_gen_rangetransition_nosecondtype_neg(CuTest *); +void test_cil_gen_rangetransition_secondtype_inparens_neg(CuTest *); +void test_cil_gen_rangetransition_noclass_neg(CuTest *); +void test_cil_gen_rangetransition_class_inparens_neg(CuTest *); +void test_cil_gen_rangetransition_nolevel_l_neg(CuTest *); +void test_cil_gen_rangetransition_nolevel_h_neg(CuTest *); +void test_cil_gen_rangetransition_extra_neg(CuTest *); + +void test_cil_gen_expr_stack_and(CuTest *); +void test_cil_gen_expr_stack_or(CuTest *); +void test_cil_gen_expr_stack_xor(CuTest *); +void test_cil_gen_expr_stack_not(CuTest *); +void test_cil_gen_expr_stack_not_noexpr_neg(CuTest *); +void test_cil_gen_expr_stack_not_extraexpr_neg(CuTest *); +void test_cil_gen_expr_stack_eq(CuTest *); +void test_cil_gen_expr_stack_neq(CuTest *); +void test_cil_gen_expr_stack_nested(CuTest *); +void test_cil_gen_expr_stack_nested_neg(CuTest *); +void test_cil_gen_expr_stack_nested_emptyargs_neg(CuTest *); +void test_cil_gen_expr_stack_nested_missingoperator_neg(CuTest *); +void test_cil_gen_expr_stack_arg1null_neg(CuTest *); +void test_cil_gen_expr_stack_arg2null_neg(CuTest *); +void test_cil_gen_expr_stack_extraarg_neg(CuTest *); +void test_cil_gen_expr_stack_currnull_neg(CuTest *); +void test_cil_gen_expr_stack_stacknull_neg(CuTest *); + +void test_cil_gen_boolif_multiplebools_true(CuTest *); +void test_cil_gen_boolif_multiplebools_false(CuTest *); +void test_cil_gen_boolif_multiplebools_unknowncond_neg(CuTest *); +void test_cil_gen_boolif_true(CuTest *); +void test_cil_gen_boolif_false(CuTest *); +void test_cil_gen_boolif_unknowncond_neg(CuTest *); +void test_cil_gen_boolif_nested(CuTest *); +void test_cil_gen_boolif_nested_neg(CuTest *); +void test_cil_gen_boolif_extra_neg(CuTest *); +void test_cil_gen_boolif_extra_parens_neg(CuTest *); +void test_cil_gen_boolif_nocond(CuTest *); +void test_cil_gen_boolif_neg(CuTest *); +void test_cil_gen_boolif_dbnull_neg(CuTest *); +void test_cil_gen_boolif_currnull_neg(CuTest *); +void test_cil_gen_boolif_astnull_neg(CuTest *); +void test_cil_gen_boolif_nocond_neg(CuTest *); +void test_cil_gen_boolif_notruelist_neg(CuTest *); +void test_cil_gen_boolif_empty_cond_neg(CuTest *); + +void test_cil_gen_else(CuTest *); +void test_cil_gen_else_neg(CuTest *); +void test_cil_gen_else_dbnull_neg(CuTest *); +void test_cil_gen_else_currnull_neg(CuTest *); +void test_cil_gen_else_astnull_neg(CuTest *); + +void test_cil_gen_tunif_multiplebools_true(CuTest *); +void test_cil_gen_tunif_multiplebools_false(CuTest *); +void test_cil_gen_tunif_multiplebools_unknowncond_neg(CuTest *); +void test_cil_gen_tunif_true(CuTest *); +void test_cil_gen_tunif_false(CuTest *); +void test_cil_gen_tunif_unknowncond_neg(CuTest *); +void test_cil_gen_tunif_nocond(CuTest *); +void test_cil_gen_tunif_nested(CuTest *); +void test_cil_gen_tunif_nested_neg(CuTest *); +void test_cil_gen_tunif_extra_neg(CuTest *); +void test_cil_gen_tunif_extra_parens_neg(CuTest *); +void test_cil_gen_tunif_neg(CuTest *); +void test_cil_gen_tunif_dbnull_neg(CuTest *); +void test_cil_gen_tunif_currnull_neg(CuTest *); +void test_cil_gen_tunif_astnull_neg(CuTest *); +void test_cil_gen_tunif_nocond_neg(CuTest *); +void test_cil_gen_tunif_notruelist_neg(CuTest *); + +void test_cil_gen_condblock_true(CuTest *); +void test_cil_gen_condblock_false(CuTest *); +void test_cil_gen_condblock_dbnull_neg(CuTest *); +void test_cil_gen_condblock_currnull_neg(CuTest *); +void test_cil_gen_condblock_astnull_neg(CuTest *); +void test_cil_gen_condblock_nocond_neg(CuTest *); +void test_cil_gen_condblock_extra_neg(CuTest *); + +void test_cil_gen_typealias(CuTest *); +void test_cil_gen_typealias_incomplete_neg(CuTest *); +void test_cil_gen_typealias_incomplete_neg2(CuTest *); +void test_cil_gen_typealias_extratype_neg(CuTest *); +void test_cil_gen_typealias_dbnull_neg(CuTest *tc); +void test_cil_gen_typealias_currnull_neg(CuTest *tc); +void test_cil_gen_typealias_astnull_neg(CuTest *tc); + +void test_cil_gen_typeattributeset(CuTest *); +void test_cil_gen_typeattributeset_and_two_types(CuTest *); +void test_cil_gen_typeattributeset_not(CuTest *); +void test_cil_gen_typeattributeset_exclude_attr(CuTest *); +void test_cil_gen_typeattributeset_exclude_neg(CuTest *); +void test_cil_gen_typeattributeset_dbnull_neg(CuTest *); +void test_cil_gen_typeattributeset_currnull_neg(CuTest *); +void test_cil_gen_typeattributeset_astnull_neg(CuTest *); +void test_cil_gen_typeattributeset_noname_neg(CuTest *); +void test_cil_gen_typeattributeset_nameinparens_neg(CuTest *); +void test_cil_gen_typeattributeset_emptylists_neg(CuTest *); +void test_cil_gen_typeattributeset_listinparens_neg(CuTest *); +void test_cil_gen_typeattributeset_extra_neg(CuTest *); + +void test_cil_gen_userbounds(CuTest *); +void test_cil_gen_userbounds_notype1_neg(CuTest *); +void test_cil_gen_userbounds_type1_inparens_neg(CuTest *); +void test_cil_gen_userbounds_notype2_neg(CuTest *); +void test_cil_gen_userbounds_type2_inparens_neg(CuTest *); +void test_cil_gen_userbounds_extra_neg(CuTest *); +void test_cil_gen_userbounds_dbnull_neg(CuTest *); +void test_cil_gen_userbounds_currnull_neg(CuTest *); +void test_cil_gen_userbounds_astnull_neg(CuTest *); + +void test_cil_gen_role(CuTest *); +void test_cil_gen_role_dbnull_neg(CuTest *tc); +void test_cil_gen_role_currnull_neg(CuTest *tc); +void test_cil_gen_role_astnull_neg(CuTest *tc); +void test_cil_gen_role_extrarole_neg(CuTest *tc); +void test_cil_gen_role_noname_neg(CuTest *tc); + +void test_cil_gen_roletransition(CuTest *); +void test_cil_gen_roletransition_currnull_neg(CuTest *); +void test_cil_gen_roletransition_astnull_neg(CuTest *); +void test_cil_gen_roletransition_srcnull_neg(CuTest *); +void test_cil_gen_roletransition_tgtnull_neg(CuTest *); +void test_cil_gen_roletransition_resultnull_neg(CuTest *); +void test_cil_gen_roletransition_extra_neg(CuTest *); + +void test_cil_gen_bool_true(CuTest *); +void test_cil_gen_bool_tunable_true(CuTest *); +void test_cil_gen_bool_false(CuTest *); +void test_cil_gen_bool_tunable_false(CuTest *); +void test_cil_gen_bool_none_neg(CuTest *); +void test_cil_gen_bool_dbnull_neg(CuTest *); +void test_cil_gen_bool_currnull_neg(CuTest *); +void test_cil_gen_bool_astnull_neg(CuTest *); +void test_cil_gen_bool_notbool_neg(CuTest *); +void test_cil_gen_bool_boolname_neg(CuTest *); +void test_cil_gen_bool_extraname_false_neg(CuTest *); +void test_cil_gen_bool_extraname_true_neg(CuTest *); + +void test_cil_gen_constrain_expr_stack_eq2_t1type(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_t1t1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_t2type(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_t2t2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_r1role(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_r1r1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_r2role(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_r2r2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_t1t2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_r1r2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_r1r2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_u1u2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_u1user(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_u1u1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_u2user(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_u2u2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_l2h2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_l2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_l1l2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_l1h1(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_l1h2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_h1l2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_h1h2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_h1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_l1l1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_l1l2_constrain_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_l1l2_constrain_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_leftkeyword_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_noexpr1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_expr1inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_noexpr2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_expr2inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_noexpr1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_expr1inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_noexpr2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_expr2inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_eq2_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_noteq(CuTest *); +void test_cil_gen_constrain_expr_stack_noteq_noexpr1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_noteq_expr1inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_noteq_noexpr2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_noteq_expr2inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_noteq_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_not(CuTest *); +void test_cil_gen_constrain_expr_stack_not_noexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_not_emptyparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_not_extraparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_or(CuTest *); +void test_cil_gen_constrain_expr_stack_or_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_or_noexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_or_emptyfirstparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_or_missingsecondexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_or_emptysecondparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_or_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_and(CuTest *); +void test_cil_gen_constrain_expr_stack_and_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_and_noexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_and_emptyfirstparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_and_missingsecondexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_and_emptysecondparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_and_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_dom(CuTest *); +void test_cil_gen_constrain_expr_stack_dom_noexpr1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_dom_expr1inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_dom_noexpr2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_dom_expr2inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_dom_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_domby(CuTest *); +void test_cil_gen_constrain_expr_stack_domby_noexpr1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_domby_expr1inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_domby_noexpr2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_domby_expr2inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_domby_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_incomp(CuTest *); +void test_cil_gen_constrain_expr_stack_incomp_noexpr1_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_incomp_expr1inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_incomp_noexpr2_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_incomp_expr2inparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_incomp_extraexpr_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_currnull_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_stacknull_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_operatorinparens_neg(CuTest *); +void test_cil_gen_constrain_expr_stack_incorrectcall_neg(CuTest *); + +void test_cil_gen_roleallow(CuTest *); +void test_cil_gen_roleallow_dbnull_neg(CuTest *); +void test_cil_gen_roleallow_currnull_neg(CuTest *); +void test_cil_gen_roleallow_astnull_neg(CuTest *); +void test_cil_gen_roleallow_srcnull_neg(CuTest *); +void test_cil_gen_roleallow_tgtnull_neg(CuTest *); +void test_cil_gen_roleallow_extra_neg(CuTest *); + +void test_cil_gen_rolebounds(CuTest *); +void test_cil_gen_rolebounds_norole1_neg(CuTest *); +void test_cil_gen_rolebounds_role1_inparens_neg(CuTest *); +void test_cil_gen_rolebounds_norole2_neg(CuTest *); +void test_cil_gen_rolebounds_role2_inparens_neg(CuTest *); +void test_cil_gen_rolebounds_extra_neg(CuTest *); +void test_cil_gen_rolebounds_dbnull_neg(CuTest *); +void test_cil_gen_rolebounds_currnull_neg(CuTest *); +void test_cil_gen_rolebounds_astnull_neg(CuTest *); + +void test_cil_gen_avrule(CuTest *); +void test_cil_gen_avrule_permset(CuTest *); +void test_cil_gen_avrule_permset_anon(CuTest *); +void test_cil_gen_avrule_extra_neg(CuTest *); +void test_cil_gen_avrule_sourceparens(CuTest *); +void test_cil_gen_avrule_sourceemptyparen_neg(CuTest *); +void test_cil_gen_avrule_targetparens(CuTest *); +void test_cil_gen_avrule_targetemptyparen_neg(CuTest *); +void test_cil_gen_avrule_currnull_neg(CuTest *tc); +void test_cil_gen_avrule_astnull_neg(CuTest *tc); +void test_cil_gen_avrule_sourcedomainnull_neg(CuTest *tc); +void test_cil_gen_avrule_targetdomainnull_neg(CuTest *tc); +void test_cil_gen_avrule_objectclassnull_neg(CuTest *tc); +void test_cil_gen_avrule_permsnull_neg(CuTest *tc); +void test_cil_gen_avrule_twolists_neg(CuTest *); +//TODO: add cases to cover parse_current->next->cl_head != NULL || parse_current->next->next->cl_head != NULL +// || parse_current->next->next->next->cl_head != NULL + +void test_cil_gen_type_rule_transition(CuTest *); +void test_cil_gen_type_rule_transition_currnull_neg(CuTest *); +void test_cil_gen_type_rule_transition_astnull_neg(CuTest *); +void test_cil_gen_type_rule_transition_srcnull_neg(CuTest *); +void test_cil_gen_type_rule_transition_tgtnull_neg(CuTest *); +void test_cil_gen_type_rule_transition_objnull_neg(CuTest *); +void test_cil_gen_type_rule_transition_resultnull_neg(CuTest *); +void test_cil_gen_type_rule_transition_extra_neg(CuTest *); + +void test_cil_gen_type_rule_change(CuTest *); +void test_cil_gen_type_rule_change_currnull_neg(CuTest *); +void test_cil_gen_type_rule_change_astnull_neg(CuTest *); +void test_cil_gen_type_rule_change_srcnull_neg(CuTest *); +void test_cil_gen_type_rule_change_tgtnull_neg(CuTest *); +void test_cil_gen_type_rule_change_objnull_neg(CuTest *); +void test_cil_gen_type_rule_change_resultnull_neg(CuTest *); +void test_cil_gen_type_rule_change_extra_neg(CuTest *); + +void test_cil_gen_type_rule_member(CuTest *); +void test_cil_gen_type_rule_member_currnull_neg(CuTest *); +void test_cil_gen_type_rule_member_astnull_neg(CuTest *); +void test_cil_gen_type_rule_member_srcnull_neg(CuTest *); +void test_cil_gen_type_rule_member_tgtnull_neg(CuTest *); +void test_cil_gen_type_rule_member_objnull_neg(CuTest *); +void test_cil_gen_type_rule_member_resultnull_neg(CuTest *); +void test_cil_gen_type_rule_member_extra_neg(CuTest *); + +void test_cil_gen_user(CuTest *); +void test_cil_gen_user_dbnull_neg(CuTest *); +void test_cil_gen_user_currnull_neg(CuTest *); +void test_cil_gen_user_astnull_neg(CuTest *); +void test_cil_gen_user_nouser_neg(CuTest *); +void test_cil_gen_user_xsinfo_neg(CuTest *); + +void test_cil_gen_userlevel(CuTest *); +void test_cil_gen_userlevel_anon_level(CuTest *); +void test_cil_gen_userlevel_anon_level_neg(CuTest *); +void test_cil_gen_userlevel_usernull_neg(CuTest *); +void test_cil_gen_userlevel_userrange_neg(CuTest *); +void test_cil_gen_userlevel_levelnull_neg(CuTest *); +void test_cil_gen_userlevel_levelrangeempty_neg(CuTest *); +void test_cil_gen_userlevel_extra_neg(CuTest *); +void test_cil_gen_userlevel_dbnull_neg(CuTest *); +void test_cil_gen_userlevel_currnull_neg(CuTest *); +void test_cil_gen_userlevel_astnull_neg(CuTest *); + +void test_cil_gen_userrange_named(CuTest *); +void test_cil_gen_userrange_anon(CuTest *); +void test_cil_gen_userrange_usernull_neg(CuTest *); +void test_cil_gen_userrange_anonuser_neg(CuTest *); +void test_cil_gen_userrange_rangenamenull_neg(CuTest *); +void test_cil_gen_userrange_anonrangeinvalid_neg(CuTest *); +void test_cil_gen_userrange_anonrangeempty_neg(CuTest *); +void test_cil_gen_userrange_extra_neg(CuTest *); +void test_cil_gen_userrange_dbnull_neg(CuTest *); +void test_cil_gen_userrange_currnull_neg(CuTest *); +void test_cil_gen_userrange_astnull_neg(CuTest *); + +void test_cil_gen_sensitivity(CuTest *); +void test_cil_gen_sensitivity_dbnull_neg(CuTest *); +void test_cil_gen_sensitivity_currnull_neg(CuTest *); +void test_cil_gen_sensitivity_astnull_neg(CuTest *); +void test_cil_gen_sensitivity_sensnull_neg(CuTest *); +void test_cil_gen_sensitivity_senslist_neg(CuTest *); +void test_cil_gen_sensitivity_extra_neg(CuTest *); + +void test_cil_gen_sensalias(CuTest *); +void test_cil_gen_sensalias_dbnull_neg(CuTest *); +void test_cil_gen_sensalias_currnull_neg(CuTest *); +void test_cil_gen_sensalias_astnull_neg(CuTest *); +void test_cil_gen_sensalias_sensnull_neg(CuTest *); +void test_cil_gen_sensalias_senslist_neg(CuTest *); +void test_cil_gen_sensalias_aliasnull_neg(CuTest *); +void test_cil_gen_sensalias_aliaslist_neg(CuTest *); +void test_cil_gen_sensalias_extra_neg(CuTest *); + +void test_cil_gen_category(CuTest *); +void test_cil_gen_category_dbnull_neg(CuTest *); +void test_cil_gen_category_astnull_neg(CuTest *); +void test_cil_gen_category_currnull_neg(CuTest *); +void test_cil_gen_category_catnull_neg(CuTest *); +void test_cil_gen_category_catlist_neg(CuTest *); +void test_cil_gen_category_extra_neg(CuTest *); + +void test_cil_gen_catset(CuTest *); +void test_cil_gen_catset_dbnull_neg(CuTest *); +void test_cil_gen_catset_currnull_neg(CuTest *); +void test_cil_gen_catset_astnull_neg(CuTest *); +void test_cil_gen_catset_namenull_neg(CuTest *); +void test_cil_gen_catset_setnull_neg(CuTest *); +void test_cil_gen_catset_namelist_neg(CuTest *); +void test_cil_gen_catset_extra_neg(CuTest *); +void test_cil_gen_catset_nodefail_neg(CuTest *); +void test_cil_gen_catset_notset_neg(CuTest *); +void test_cil_gen_catset_settolistfail_neg(CuTest *); + +void test_cil_gen_catalias(CuTest *); +void test_cil_gen_catalias_dbnull_neg(CuTest *); +void test_cil_gen_catalias_currnull_neg(CuTest *); +void test_cil_gen_catalias_astnull_neg(CuTest *); +void test_cil_gen_catalias_catnull_neg(CuTest *); +void test_cil_gen_catalias_aliasnull_neg(CuTest *); +void test_cil_gen_catalias_extra_neg(CuTest *); + +void test_cil_gen_catrange(CuTest *); +void test_cil_gen_catrange_noname_neg(CuTest *); +void test_cil_gen_catrange_norange_neg(CuTest *); +void test_cil_gen_catrange_emptyrange_neg(CuTest *); +void test_cil_gen_catrange_extrarange_neg(CuTest *); +void test_cil_gen_catrange_dbnull_neg(CuTest *); +void test_cil_gen_catrange_currnull_neg(CuTest *); +void test_cil_gen_catrange_astnull_neg(CuTest *); +void test_cil_gen_catrange_extra_neg(CuTest *); + +void test_cil_gen_roletype(CuTest *tc); +void test_cil_gen_roletype_currnull_neg(CuTest *tc); +void test_cil_gen_roletype_dbnull_neg(CuTest *tc); +void test_cil_gen_roletype_astnull_neg(CuTest *tc); +void test_cil_gen_roletype_empty_neg(CuTest *tc); +void test_cil_gen_roletype_rolelist_neg(CuTest *tc); +void test_cil_gen_roletype_roletype_sublist_neg(CuTest *tc); +void test_cil_gen_roletype_typelist_neg(CuTest *tc); + +void test_cil_gen_userrole(CuTest *tc); +void test_cil_gen_userrole_currnull_neg(CuTest *tc); +void test_cil_gen_userrole_dbnull_neg(CuTest *tc); +void test_cil_gen_userrole_astnull_neg(CuTest *tc); +void test_cil_gen_userrole_empty_neg(CuTest *tc); +void test_cil_gen_userrole_userlist_neg(CuTest *tc); +void test_cil_gen_userrole_userrole_sublist_neg(CuTest *tc); +void test_cil_gen_userrole_rolelist_neg(CuTest *tc); + +void test_cil_gen_classcommon(CuTest *tc); +void test_cil_gen_classcommon_dbnull_neg(CuTest *tc); +void test_cil_gen_classcommon_currnull_neg(CuTest *tc); +void test_cil_gen_classcommon_astnull_neg(CuTest *tc); +void test_cil_gen_classcommon_missingclassname_neg(CuTest *tc); +void test_cil_gen_classcommon_noperms_neg(CuTest *tc); +void test_cil_gen_classcommon_extraperms_neg(CuTest *tc); + +void test_cil_gen_catorder(CuTest *tc); +void test_cil_gen_catorder_dbnull_neg(CuTest *tc); +void test_cil_gen_catorder_currnull_neg(CuTest *tc); +void test_cil_gen_catorder_astnull_neg(CuTest *tc); +void test_cil_gen_catorder_missingcats_neg(CuTest *tc); +void test_cil_gen_catorder_nosublist_neg(CuTest *tc); +void test_cil_gen_catorder_nestedcat_neg(CuTest *tc); + +void test_cil_gen_dominance(CuTest *tc); +void test_cil_gen_dominance_dbnull_neg(CuTest *tc); +void test_cil_gen_dominance_currnull_neg(CuTest *tc); +void test_cil_gen_dominance_astnull_neg(CuTest *tc); +void test_cil_gen_dominance_nosensitivities_neg(CuTest *tc); +void test_cil_gen_dominance_nosublist_neg(CuTest *tc); + +void test_cil_gen_senscat(CuTest *tc); +void test_cil_gen_senscat_nosublist(CuTest *); +void test_cil_gen_senscat_dbnull_neg(CuTest *tc); +void test_cil_gen_senscat_currnull_neg(CuTest *tc); +void test_cil_gen_senscat_astnull_neg(CuTest *tc); +void test_cil_gen_senscat_nosensitivities_neg(CuTest *tc); +void test_cil_gen_senscat_sublist_neg(CuTest *); +void test_cil_gen_senscat_nocat_neg(CuTest *); + +void test_cil_fill_level(CuTest *tc); +void test_cil_fill_level_sensnull_neg(CuTest *tc); +void test_cil_fill_level_levelnull_neg(CuTest *tc); +void test_cil_fill_level_nocat(CuTest *tc); +void test_cil_fill_level_emptycat_neg(CuTest *tc); + +void test_cil_gen_level(CuTest *tc); +void test_cil_gen_level_nameinparens_neg(CuTest *tc); +void test_cil_gen_level_emptysensparens_neg(CuTest *tc); +void test_cil_gen_level_extra_neg(CuTest *tc); +void test_cil_gen_level_emptycat_neg(CuTest *tc); +void test_cil_gen_level_noname_neg(CuTest *tc); +void test_cil_gen_level_nosens_neg(CuTest *tc); +void test_cil_gen_level_dbnull_neg(CuTest *tc); +void test_cil_gen_level_currnull_neg(CuTest *tc); +void test_cil_gen_level_astnull_neg(CuTest *tc); + +void test_cil_gen_levelrange(CuTest *tc); +void test_cil_gen_levelrange_rangeinvalid_neg(CuTest *tc); +void test_cil_gen_levelrange_namenull_neg(CuTest *tc); +void test_cil_gen_levelrange_rangenull_neg(CuTest *tc); +void test_cil_gen_levelrange_rangeempty_neg(CuTest *tc); +void test_cil_gen_levelrange_extra_neg(CuTest *tc); +void test_cil_gen_levelrange_dbnull_neg(CuTest *tc); +void test_cil_gen_levelrange_currnull_neg(CuTest *tc); +void test_cil_gen_levelrange_astnull_neg(CuTest *tc); + +void test_cil_gen_constrain(CuTest *tc); +void test_cil_gen_constrain_neg(CuTest *tc); +void test_cil_gen_constrain_classset_neg(CuTest *tc); +void test_cil_gen_constrain_classset_noclass_neg(CuTest *tc); +void test_cil_gen_constrain_classset_noperm_neg(CuTest *tc); +void test_cil_gen_constrain_permset_neg(CuTest *tc); +void test_cil_gen_constrain_permset_noclass_neg(CuTest *tc); +void test_cil_gen_constrain_permset_noperm_neg(CuTest *tc); +void test_cil_gen_constrain_expression_neg(CuTest *tc); +void test_cil_gen_constrain_dbnull_neg(CuTest *tc); +void test_cil_gen_constrain_currnull_neg(CuTest *tc); +void test_cil_gen_constrain_astnull_neg(CuTest *tc); + +void test_cil_fill_context(CuTest *tc); +void test_cil_fill_context_unnamedlvl(CuTest *tc); +void test_cil_fill_context_nocontext_neg(CuTest *tc); +void test_cil_fill_context_nouser_neg(CuTest *tc); +void test_cil_fill_context_norole_neg(CuTest *tc); +void test_cil_fill_context_notype_neg(CuTest *tc); +void test_cil_fill_context_nolowlvl_neg(CuTest *tc); +void test_cil_fill_context_nohighlvl_neg(CuTest *tc); +void test_cil_fill_context_unnamedlvl_nocontextlow_neg(CuTest *tc); +void test_cil_fill_context_unnamedlvl_nocontexthigh_neg(CuTest *tc); + +void test_cil_gen_context(CuTest *tc); +void test_cil_gen_context_notinparens_neg(CuTest *tc); +void test_cil_gen_context_extralevel_neg(CuTest *tc); +void test_cil_gen_context_emptycontext_neg(CuTest *tc); +void test_cil_gen_context_extra_neg(CuTest *tc); +void test_cil_gen_context_doubleparen_neg(CuTest *tc); +void test_cil_gen_context_norole_neg(CuTest *tc); +void test_cil_gen_context_roleinparens_neg(CuTest *tc); +void test_cil_gen_context_notype_neg(CuTest *tc); +void test_cil_gen_context_typeinparens_neg(CuTest *tc); +void test_cil_gen_context_nolevels_neg(CuTest *tc); +void test_cil_gen_context_nosecondlevel_neg(CuTest *tc); +void test_cil_gen_context_noname_neg(CuTest *tc); +void test_cil_gen_context_nouser_neg(CuTest *tc); +void test_cil_gen_context_dbnull_neg(CuTest *tc); +void test_cil_gen_context_currnull_neg(CuTest *tc); +void test_cil_gen_context_astnull_neg(CuTest *tc); + +void test_cil_gen_filecon_file(CuTest *tc); +void test_cil_gen_filecon_dir(CuTest *tc); +void test_cil_gen_filecon_char(CuTest *tc); +void test_cil_gen_filecon_block(CuTest *tc); +void test_cil_gen_filecon_socket(CuTest *tc); +void test_cil_gen_filecon_pipe(CuTest *tc); +void test_cil_gen_filecon_symlink(CuTest *tc); +void test_cil_gen_filecon_any(CuTest *tc); +void test_cil_gen_filecon_neg(CuTest *tc); +void test_cil_gen_filecon_anon_context(CuTest *tc); +void test_cil_gen_filecon_dbnull_neg(CuTest *tc); +void test_cil_gen_filecon_currnull_neg(CuTest *tc); +void test_cil_gen_filecon_astnull_neg(CuTest *tc); +void test_cil_gen_filecon_str1null_neg(CuTest *tc); +void test_cil_gen_filecon_str1_inparens_neg(CuTest *tc); +void test_cil_gen_filecon_str2null_neg(CuTest *tc); +void test_cil_gen_filecon_str2_inparens_neg(CuTest *tc); +void test_cil_gen_filecon_classnull_neg(CuTest *tc); +void test_cil_gen_filecon_class_inparens_neg(CuTest *tc); +void test_cil_gen_filecon_contextnull_neg(CuTest *tc); +void test_cil_gen_filecon_context_neg(CuTest *tc); +void test_cil_gen_filecon_extra_neg(CuTest *tc); + +void test_cil_gen_portcon_udp(CuTest *tc); +void test_cil_gen_portcon_tcp(CuTest *tc); +void test_cil_gen_portcon_unknownprotocol_neg(CuTest *tc); +void test_cil_gen_portcon_anon_context(CuTest *tc); +void test_cil_gen_portcon_portrange(CuTest *tc); +void test_cil_gen_portcon_portrange_one_neg(CuTest *tc); +void test_cil_gen_portcon_portrange_morethanone_neg(CuTest *tc); +void test_cil_gen_portcon_singleport_neg(CuTest *tc); +void test_cil_gen_portcon_lowport_neg(CuTest *tc); +void test_cil_gen_portcon_highport_neg(CuTest *tc); +void test_cil_gen_portcon_dbnull_neg(CuTest *tc); +void test_cil_gen_portcon_currnull_neg(CuTest *tc); +void test_cil_gen_portcon_astnull_neg(CuTest *tc); +void test_cil_gen_portcon_str1null_neg(CuTest *tc); +void test_cil_gen_portcon_str1parens_neg(CuTest *tc); +void test_cil_gen_portcon_portnull_neg(CuTest *tc); +void test_cil_gen_portcon_contextnull_neg(CuTest *tc); +void test_cil_gen_portcon_context_neg(CuTest *tc); +void test_cil_gen_portcon_extra_neg(CuTest *tc); + +void test_cil_fill_ipaddr(CuTest *tc); +void test_cil_fill_ipaddr_addrnodenull_neg(CuTest *tc); +void test_cil_fill_ipaddr_addrnull_neg(CuTest *tc); +void test_cil_fill_ipaddr_addrinparens_neg(CuTest *tc); +void test_cil_fill_ipaddr_extra_neg(CuTest *tc); + +void test_cil_gen_nodecon(CuTest *tc); +void test_cil_gen_nodecon_anon_context(CuTest *tc); +void test_cil_gen_nodecon_dbnull_neg(CuTest *tc); +void test_cil_gen_nodecon_currnull_neg(CuTest *tc); +void test_cil_gen_nodecon_astnull_neg(CuTest *tc); +void test_cil_gen_nodecon_ipnull_neg(CuTest *tc); +void test_cil_gen_nodecon_ipanon(CuTest *tc); +void test_cil_gen_nodecon_ipanon_neg(CuTest *tc); +void test_cil_gen_nodecon_netmasknull_neg(CuTest *tc); +void test_cil_gen_nodecon_netmaskanon(CuTest *tc); +void test_cil_gen_nodecon_netmaskanon_neg(CuTest *tc); +void test_cil_gen_nodecon_contextnull_neg(CuTest *tc); +void test_cil_gen_nodecon_context_neg(CuTest *tc); +void test_cil_gen_nodecon_extra_neg(CuTest *tc); + +void test_cil_gen_genfscon(CuTest *tc); +void test_cil_gen_genfscon_anon_context(CuTest *tc); +void test_cil_gen_genfscon_dbnull_neg(CuTest *tc); +void test_cil_gen_genfscon_currnull_neg(CuTest *tc); +void test_cil_gen_genfscon_astnull_neg(CuTest *tc); +void test_cil_gen_genfscon_typenull_neg(CuTest *tc); +void test_cil_gen_genfscon_typeparens_neg(CuTest *tc); +void test_cil_gen_genfscon_pathnull_neg(CuTest *tc); +void test_cil_gen_genfscon_pathparens_neg(CuTest *tc); +void test_cil_gen_genfscon_contextnull_neg(CuTest *tc); +void test_cil_gen_genfscon_context_neg(CuTest *tc); +void test_cil_gen_genfscon_extra_neg(CuTest *tc); + +void test_cil_gen_netifcon(CuTest *tc); +void test_cil_gen_netifcon_nested(CuTest *tc); +void test_cil_gen_netifcon_nested_neg(CuTest *tc); +void test_cil_gen_netifcon_nested_emptysecondlist_neg(CuTest *tc); +void test_cil_gen_netifcon_extra_nested_secondlist_neg(CuTest *tc); +void test_cil_gen_netifcon_nested_missingobjects_neg(CuTest *tc); +void test_cil_gen_netifcon_nested_secondnested_missingobjects_neg(CuTest *tc); +void test_cil_gen_netifcon_dbnull_neg(CuTest *tc); +void test_cil_gen_netifcon_currnull_neg(CuTest *tc); +void test_cil_gen_netifcon_astnull_neg(CuTest *tc); +void test_cil_gen_netifcon_ethmissing_neg(CuTest *tc); +void test_cil_gen_netifcon_interfacemissing_neg(CuTest *tc); +void test_cil_gen_netifcon_packetmissing_neg(CuTest *tc); + +void test_cil_gen_pirqcon(CuTest *tc); +void test_cil_gen_pirqcon_pirqnotint_neg(CuTest *tc); +void test_cil_gen_pirqcon_nopirq_neg(CuTest *tc); +void test_cil_gen_pirqcon_pirqrange_neg(CuTest *tc); +void test_cil_gen_pirqcon_nocontext_neg(CuTest *tc); +void test_cil_gen_pirqcon_anoncontext_neg(CuTest *tc); +void test_cil_gen_pirqcon_extra_neg(CuTest *tc); +void test_cil_gen_pirqcon_dbnull_neg(CuTest *tc); +void test_cil_gen_pirqcon_currnull_neg(CuTest *tc); +void test_cil_gen_pirqcon_astnull_neg(CuTest *tc); + +void test_cil_gen_iomemcon(CuTest *tc); +void test_cil_gen_iomemcon_iomemrange(CuTest *tc); +void test_cil_gen_iomemcon_iomemrange_firstnotint_neg(CuTest *tc); +void test_cil_gen_iomemcon_iomemrange_secondnotint_neg(CuTest *tc); +void test_cil_gen_iomemcon_iomemrange_empty_neg(CuTest *tc); +void test_cil_gen_iomemcon_iomemrange_singleiomem_neg(CuTest *tc); +void test_cil_gen_iomemcon_iomemrange_morethantwoiomem_neg(CuTest *tc); +void test_cil_gen_iomemcon_iomemnotint_neg(CuTest *tc); +void test_cil_gen_iomemcon_noiomem_neg(CuTest *tc); +void test_cil_gen_iomemcon_nocontext_neg(CuTest *tc); +void test_cil_gen_iomemcon_anoncontext_neg(CuTest *tc); +void test_cil_gen_iomemcon_extra_neg(CuTest *tc); +void test_cil_gen_iomemcon_dbnull_neg(CuTest *tc); +void test_cil_gen_iomemcon_currnull_neg(CuTest *tc); +void test_cil_gen_iomemcon_astnull_neg(CuTest *tc); + +void test_cil_gen_ioportcon(CuTest *tc); +void test_cil_gen_ioportcon_ioportrange(CuTest *tc); +void test_cil_gen_ioportcon_ioportrange_firstnotint_neg(CuTest *tc); +void test_cil_gen_ioportcon_ioportrange_secondnotint_neg(CuTest *tc); +void test_cil_gen_ioportcon_ioportrange_empty_neg(CuTest *tc); +void test_cil_gen_ioportcon_ioportrange_singleioport_neg(CuTest *tc); +void test_cil_gen_ioportcon_ioportrange_morethantwoioport_neg(CuTest *tc); +void test_cil_gen_ioportcon_ioportnotint_neg(CuTest *tc); +void test_cil_gen_ioportcon_noioport_neg(CuTest *tc); +void test_cil_gen_ioportcon_nocontext_neg(CuTest *tc); +void test_cil_gen_ioportcon_anoncontext_neg(CuTest *tc); +void test_cil_gen_ioportcon_extra_neg(CuTest *tc); +void test_cil_gen_ioportcon_dbnull_neg(CuTest *tc); +void test_cil_gen_ioportcon_currnull_neg(CuTest *tc); +void test_cil_gen_ioportcon_astnull_neg(CuTest *tc); + +void test_cil_gen_pcidevicecon(CuTest *tc); +void test_cil_gen_pcidevicecon_pcidevicenotint_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_nopcidevice_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_pcidevicerange_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_nocontext_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_anoncontext_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_extra_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_dbnull_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_currnull_neg(CuTest *tc); +void test_cil_gen_pcidevicecon_astnull_neg(CuTest *tc); + +void test_cil_gen_fsuse_anoncontext(CuTest *tc); +void test_cil_gen_fsuse_anoncontext_neg(CuTest *tc); +void test_cil_gen_fsuse_xattr(CuTest *tc); +void test_cil_gen_fsuse_task(CuTest *tc); +void test_cil_gen_fsuse_transition(CuTest *tc); +void test_cil_gen_fsuse_invalidtype_neg(CuTest *tc); +void test_cil_gen_fsuse_notype_neg(CuTest *tc); +void test_cil_gen_fsuse_typeinparens_neg(CuTest *tc); +void test_cil_gen_fsuse_nofilesystem_neg(CuTest *tc); +void test_cil_gen_fsuse_filesysteminparens_neg(CuTest *tc); +void test_cil_gen_fsuse_nocontext_neg(CuTest *tc); +void test_cil_gen_fsuse_emptyconparens_neg(CuTest *tc); +void test_cil_gen_fsuse_extra_neg(CuTest *tc); +void test_cil_gen_fsuse_dbnull_neg(CuTest *tc); +void test_cil_gen_fsuse_currnull_neg(CuTest *tc); +void test_cil_gen_fsuse_astnull_neg(CuTest *tc); + +void test_cil_gen_macro_noparams(CuTest *tc); +void test_cil_gen_macro_type(CuTest *tc); +void test_cil_gen_macro_role(CuTest *tc); +void test_cil_gen_macro_user(CuTest *tc); +void test_cil_gen_macro_sensitivity(CuTest *tc); +void test_cil_gen_macro_category(CuTest *tc); +void test_cil_gen_macro_catset(CuTest *tc); +void test_cil_gen_macro_level(CuTest *tc); +void test_cil_gen_macro_class(CuTest *tc); +void test_cil_gen_macro_classmap(CuTest *tc); +void test_cil_gen_macro_permset(CuTest *tc); +void test_cil_gen_macro_duplicate(CuTest *tc); +void test_cil_gen_macro_duplicate_neg(CuTest *tc); +void test_cil_gen_macro_unknown_neg(CuTest *tc); +void test_cil_gen_macro_dbnull_neg(CuTest *tc); +void test_cil_gen_macro_currnull_neg(CuTest *tc); +void test_cil_gen_macro_astnull_neg(CuTest *tc); +void test_cil_gen_macro_unnamed_neg(CuTest *tc); +void test_cil_gen_macro_noparam_name_neg(CuTest *tc); +void test_cil_gen_macro_noparam_neg(CuTest *tc); +void test_cil_gen_macro_nosecondparam_neg(CuTest *tc); +void test_cil_gen_macro_emptyparam_neg(CuTest *tc); +void test_cil_gen_macro_paramcontainsperiod_neg(CuTest *tc); + +void test_cil_gen_call(CuTest *tc); +void test_cil_gen_call_noargs(CuTest *tc); +void test_cil_gen_call_anon(CuTest *tc); +void test_cil_gen_call_empty_call_neg(CuTest *tc); +void test_cil_gen_call_dbnull_neg(CuTest *tc); +void test_cil_gen_call_currnull_neg(CuTest *tc); +void test_cil_gen_call_astnull_neg(CuTest *tc); +void test_cil_gen_call_name_inparens_neg(CuTest *tc); +void test_cil_gen_call_noname_neg(CuTest *tc); + +void test_cil_gen_optional(CuTest *tc); +void test_cil_gen_optional_emptyoptional(CuTest *tc); +void test_cil_gen_optional_dbnull_neg(CuTest *tc); +void test_cil_gen_optional_currnull_neg(CuTest *tc); +void test_cil_gen_optional_astnull_neg(CuTest *tc); +void test_cil_gen_optional_unnamed_neg(CuTest *tc); +void test_cil_gen_optional_extra_neg(CuTest *tc); +void test_cil_gen_optional_nameinparens_neg(CuTest *tc); +void test_cil_gen_optional_norule_neg(CuTest *tc); + +void test_cil_gen_policycap(CuTest *tc); +void test_cil_gen_policycap_noname_neg(CuTest *tc); +void test_cil_gen_policycap_nameinparens_neg(CuTest *tc); +void test_cil_gen_policycap_extra_neg(CuTest *tc); +void test_cil_gen_policycap_dbnull_neg(CuTest *tc); +void test_cil_gen_policycap_currnull_neg(CuTest *tc); +void test_cil_gen_policycap_astnull_neg(CuTest *tc); + +void test_cil_gen_ipaddr_ipv4(CuTest *tc); +void test_cil_gen_ipaddr_ipv4_neg(CuTest *tc); +void test_cil_gen_ipaddr_ipv6(CuTest *tc); +void test_cil_gen_ipaddr_ipv6_neg(CuTest *tc); +void test_cil_gen_ipaddr_noname_neg(CuTest *tc); +void test_cil_gen_ipaddr_nameinparens_neg(CuTest *tc); +void test_cil_gen_ipaddr_noip_neg(CuTest *tc); +void test_cil_gen_ipaddr_ipinparens_neg(CuTest *tc); +void test_cil_gen_ipaddr_extra_neg(CuTest *tc); +void test_cil_gen_ipaddr_dbnull_neg(CuTest *tc); +void test_cil_gen_ipaddr_currnull_neg(CuTest *tc); +void test_cil_gen_ipaddr_astnull_neg(CuTest *tc); +/* +cil_build_ast test cases +*/ +void test_cil_build_ast(CuTest *); +void test_cil_build_ast_dbnull_neg(CuTest *); +void test_cil_build_ast_astnull_neg(CuTest *); +void test_cil_build_ast_suberr_neg(CuTest *); +void test_cil_build_ast_treenull_neg(CuTest *); + +void test_cil_build_ast_node_helper_block(CuTest *); +void test_cil_build_ast_node_helper_block_neg(CuTest *); + +void test_cil_build_ast_node_helper_blockinherit(CuTest *); +void test_cil_build_ast_node_helper_blockinherit_neg(CuTest *); + +void test_cil_build_ast_node_helper_permset(CuTest *); +void test_cil_build_ast_node_helper_permset_neg(CuTest *); + +void test_cil_build_ast_node_helper_in(CuTest *); +void test_cil_build_ast_node_helper_in_neg(CuTest *); + +void test_cil_build_ast_node_helper_class(CuTest *); +void test_cil_build_ast_node_helper_class_neg(CuTest *); + +void test_cil_build_ast_node_helper_classpermset(CuTest *); +void test_cil_build_ast_node_helper_classpermset_neg(CuTest *); + +void test_cil_build_ast_node_helper_classmap(CuTest *); +void test_cil_build_ast_node_helper_classmap_neg(CuTest *); + +void test_cil_build_ast_node_helper_classmapping(CuTest *); +void test_cil_build_ast_node_helper_classmapping_neg(CuTest *); + +void test_cil_build_ast_node_helper_common(CuTest *); +void test_cil_build_ast_node_helper_common_neg(CuTest *); + +void test_cil_build_ast_node_helper_sid(CuTest *); +void test_cil_build_ast_node_helper_sid_neg(CuTest *); + +void test_cil_build_ast_node_helper_sidcontext(CuTest *); +void test_cil_build_ast_node_helper_sidcontext_neg(CuTest *); + +void test_cil_build_ast_node_helper_user(CuTest *); +void test_cil_build_ast_node_helper_user_neg(CuTest *); + +void test_cil_build_ast_node_helper_userlevel(CuTest *); +void test_cil_build_ast_node_helper_userlevel_neg(CuTest *); + +void test_cil_build_ast_node_helper_userrange(CuTest *); +void test_cil_build_ast_node_helper_userrange_neg(CuTest *); + +void test_cil_build_ast_node_helper_type(CuTest *); +void test_cil_build_ast_node_helper_type_neg(CuTest *); + +void test_cil_build_ast_node_helper_typeattribute(CuTest *); +void test_cil_build_ast_node_helper_typeattribute_neg(CuTest *); + +void test_cil_build_ast_node_helper_boolif(CuTest *); +void test_cil_build_ast_node_helper_boolif_neg(CuTest *); + +void test_cil_build_ast_node_helper_tunif(CuTest *); +void test_cil_build_ast_node_helper_tunif_neg(CuTest *); + +void test_cil_build_ast_node_helper_condblock_true(CuTest *); +void test_cil_build_ast_node_helper_condblock_true_neg(CuTest *); +void test_cil_build_ast_node_helper_condblock_false(CuTest *); +void test_cil_build_ast_node_helper_condblock_false_neg(CuTest *); + +void test_cil_build_ast_node_helper_typealias(CuTest *); +void test_cil_build_ast_node_helper_typealias_notype_neg(CuTest *); + +void test_cil_build_ast_node_helper_typebounds(CuTest *); +void test_cil_build_ast_node_helper_typebounds_neg(CuTest *); + +void test_cil_build_ast_node_helper_typepermissive(CuTest *); +void test_cil_build_ast_node_helper_typepermissive_neg(CuTest *); + +void test_cil_build_ast_node_helper_nametypetransition(CuTest *); +void test_cil_build_ast_node_helper_nametypetransition_neg(CuTest *); + +void test_cil_build_ast_node_helper_rangetransition(CuTest *); +void test_cil_build_ast_node_helper_rangetransition_neg(CuTest *); + +void test_cil_build_ast_node_helper_typeattributeset(CuTest *); +void test_cil_build_ast_node_helper_typeattributeset_neg(CuTest *); + +void test_cil_build_ast_node_helper_userbounds(CuTest *); +void test_cil_build_ast_node_helper_userbounds_neg(CuTest *); + +void test_cil_build_ast_node_helper_role(CuTest *); +void test_cil_build_ast_node_helper_role_neg(CuTest *); + +void test_cil_build_ast_node_helper_roletransition(CuTest *); +void test_cil_build_ast_node_helper_roletransition_neg(CuTest *); + +void test_cil_build_ast_node_helper_roleallow(CuTest *); +void test_cil_build_ast_node_helper_roleallow_neg(CuTest *); + +void test_cil_build_ast_node_helper_rolebounds(CuTest *); +void test_cil_build_ast_node_helper_rolebounds_neg(CuTest *); + +void test_cil_build_ast_node_helper_avrule_allow(CuTest *); +void test_cil_build_ast_node_helper_avrule_allow_neg(CuTest *); + +void test_cil_build_ast_node_helper_avrule_auditallow(CuTest *); +void test_cil_build_ast_node_helper_avrule_auditallow_neg(CuTest *); + +void test_cil_build_ast_node_helper_avrule_dontaudit(CuTest *); +void test_cil_build_ast_node_helper_avrule_dontaudit_neg(CuTest *); + +void test_cil_build_ast_node_helper_avrule_neverallow(CuTest *); +void test_cil_build_ast_node_helper_avrule_neverallow_neg(CuTest *); + +void test_cil_build_ast_node_helper_type_rule_transition(CuTest *); +void test_cil_build_ast_node_helper_type_rule_transition_neg(CuTest *); + +void test_cil_build_ast_node_helper_type_rule_change(CuTest *); +void test_cil_build_ast_node_helper_type_rule_change_neg(CuTest *); + +void test_cil_build_ast_node_helper_type_rule_member(CuTest *); +void test_cil_build_ast_node_helper_type_rule_member_neg(CuTest *); + +void test_cil_build_ast_node_helper_bool(CuTest *); +void test_cil_build_ast_node_helper_bool_neg(CuTest *); + +void test_cil_build_ast_node_helper_bool_tunable(CuTest *); +void test_cil_build_ast_node_helper_bool_tunable_neg(CuTest *); + +void test_cil_build_ast_node_helper_else(CuTest *); +void test_cil_build_ast_node_helper_else_neg(CuTest *); + +void test_cil_build_ast_node_helper_sensitivity(CuTest *); +void test_cil_build_ast_node_helper_sensitivity_neg(CuTest *); + +void test_cil_build_ast_node_helper_sensalias(CuTest *); +void test_cil_build_ast_node_helper_sensalias_neg(CuTest *); + +void test_cil_build_ast_node_helper_category(CuTest *); +void test_cil_build_ast_node_helper_category_neg(CuTest *); + +void test_cil_build_ast_node_helper_catset(CuTest *tc); +void test_cil_build_ast_node_helper_catset_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_catorder(CuTest *tc); +void test_cil_build_ast_node_helper_catorder_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_catalias(CuTest *tc); +void test_cil_build_ast_node_helper_catalias_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_catrange(CuTest *tc); +void test_cil_build_ast_node_helper_catrange_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_roletype(CuTest *tc); +void test_cil_build_ast_node_helper_roletype_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_userrole(CuTest *tc); +void test_cil_build_ast_node_helper_userrole_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_classcommon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_classcommon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_dominance(CuTest *tc); +void test_cil_build_ast_node_helper_gen_dominance_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_senscat(CuTest *tc); +void test_cil_build_ast_node_helper_gen_senscat_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_level(CuTest *tc); +void test_cil_build_ast_node_helper_gen_level_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_levelrange(CuTest *tc); +void test_cil_build_ast_node_helper_gen_levelrange_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_constrain(CuTest *tc); +void test_cil_build_ast_node_helper_gen_constrain_neg(CuTest *tc); +void test_cil_build_ast_node_helper_gen_mlsconstrain(CuTest *tc); +void test_cil_build_ast_node_helper_gen_mlsconstrain_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_context(CuTest *tc); +void test_cil_build_ast_node_helper_gen_context_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_filecon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_filecon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_portcon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_portcon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_nodecon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_nodecon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_genfscon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_genfscon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_netifcon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_netifcon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_pirqcon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_pirqcon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_iomemcon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_iomemcon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_ioportcon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_ioportcon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_pcidevicecon(CuTest *tc); +void test_cil_build_ast_node_helper_gen_pcidevicecon_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_fsuse(CuTest *tc); +void test_cil_build_ast_node_helper_gen_fsuse_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_macro(CuTest *tc); +void test_cil_build_ast_node_helper_gen_macro_neg(CuTest *tc); +void test_cil_build_ast_node_helper_gen_macro_nested_macro_neg(CuTest *tc); +void test_cil_build_ast_node_helper_gen_macro_nested_tunif_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_call(CuTest *tc); +void test_cil_build_ast_node_helper_gen_call_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_optional(CuTest *tc); +void test_cil_build_ast_node_helper_gen_optional_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_policycap(CuTest *tc); +void test_cil_build_ast_node_helper_gen_policycap_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_gen_ipaddr(CuTest *tc); +void test_cil_build_ast_node_helper_gen_ipaddr_neg(CuTest *tc); + +void test_cil_build_ast_node_helper_extraargsnull_neg(CuTest *); + +void test_cil_build_ast_last_child_helper(CuTest *); +void test_cil_build_ast_last_child_helper_extraargsnull_neg(CuTest *); +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_copy_ast.c b/kernel/libsepol/cil/test/unit/test_cil_copy_ast.c new file mode 100644 index 00000000..5cbc6fac --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_copy_ast.c @@ -0,0 +1,2571 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include "CuTest.h" +#include "CilTest.h" + +#include "../../src/cil_internal.h" +#include "../../src/cil_copy_ast.h" +#include "../../src/cil_build_ast.h" +#include "../../src/cil_resolve_ast.h" + +#define CIL_TEST_SYM_SIZE 1 + +int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void *extra_args); + +struct cil_args_copy { + struct cil_tree_node *dest; + struct cil_db *db; +}; + +struct cil_args_copy *gen_copy_args(struct cil_tree_node *node, struct cil_db *db) +{ + struct cil_args_copy *args = cil_malloc(sizeof(*args)); + args->dest = node; + args->db = db; + + return args; +} + +void test_cil_copy_list(CuTest *tc) { + char *line[] = {"(", "foo1", "foo2", ")", NULL}; + + struct cil_tree *test_tree; + struct cil_list *cil_l; + + gen_test_tree(&test_tree, line); + cil_list_init(&cil_l); + + cil_set_to_list(test_tree->root->cl_head, cil_l, 1); + + struct cil_list *copy_list; + cil_list_init(©_list); + + int rc =cil_copy_list(cil_l, ©_list); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, copy_list->head->data, cil_l->head->data); + CuAssertStrEquals(tc, copy_list->head->next->data, cil_l->head->next->data); + CuAssertIntEquals(tc, copy_list->head->flavor, cil_l->head->flavor); + CuAssertIntEquals(tc, copy_list->head->next->flavor, cil_l->head->next->flavor); +} + +void test_cil_copy_list_sublist(CuTest *tc) { + char *line[] = {"(", "foo1", "foo2", "(", "foo3", ")", ")", NULL}; + + struct cil_tree *test_tree; + struct cil_list *cil_l; + + gen_test_tree(&test_tree, line); + cil_list_init(&cil_l); + + cil_set_to_list(test_tree->root->cl_head, cil_l, 1); + + struct cil_list *copy_list; + cil_list_init(©_list); + + int rc = cil_copy_list(cil_l, ©_list); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, copy_list->head->data, cil_l->head->data); + CuAssertStrEquals(tc, copy_list->head->next->data, cil_l->head->next->data); + CuAssertStrEquals(tc, ((struct cil_list *)copy_list->head->next->next->data)->head->data, ((struct cil_list *)cil_l->head->next->next->data)->head->data); + CuAssertIntEquals(tc, copy_list->head->flavor, cil_l->head->flavor); + CuAssertIntEquals(tc, copy_list->head->next->flavor, cil_l->head->next->flavor); + CuAssertIntEquals(tc, ((struct cil_list *)copy_list->head->next->next->data)->head->flavor, ((struct cil_list *)cil_l->head->next->next->data)->head->flavor); +} + +void test_cil_copy_list_sublist_extra(CuTest *tc) { + char *line[] = {"(", "foo1", "foo2", "(", "foo3", ")", "foo4", ")", NULL}; + + struct cil_tree *test_tree; + struct cil_list *cil_l; + + gen_test_tree(&test_tree, line); + cil_list_init(&cil_l); + + cil_set_to_list(test_tree->root->cl_head, cil_l, 1); + + struct cil_list *copy_list; + cil_list_init(©_list); + + int rc = cil_copy_list(cil_l, ©_list); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, copy_list->head->data, cil_l->head->data); + CuAssertStrEquals(tc, copy_list->head->next->data, cil_l->head->next->data); + CuAssertStrEquals(tc, ((struct cil_list *)copy_list->head->next->next->data)->head->data, ((struct cil_list *)cil_l->head->next->next->data)->head->data); + CuAssertStrEquals(tc, copy_list->head->next->next->next->data, cil_l->head->next->next->next->data); + CuAssertIntEquals(tc, copy_list->head->flavor, cil_l->head->flavor); + CuAssertIntEquals(tc, copy_list->head->next->flavor, cil_l->head->next->flavor); + CuAssertIntEquals(tc, ((struct cil_list *)copy_list->head->next->next->data)->head->flavor, ((struct cil_list *)cil_l->head->next->next->data)->head->flavor); + CuAssertIntEquals(tc, copy_list->head->next->next->next->flavor, cil_l->head->next->next->next->flavor); +} + +void test_cil_copy_list_orignull_neg(CuTest *tc) { + char *line[] = {"(", "foo1", "foo2", ")", NULL}; + + struct cil_tree *test_tree; + struct cil_list *cil_l = NULL; + + gen_test_tree(&test_tree, line); + + struct cil_list *copy_list; + cil_list_init(©_list); + + int rc = cil_copy_list(cil_l, ©_list); + CuAssertIntEquals(tc, rc, SEPOL_ERR); + CuAssertPtrEquals(tc, copy_list->head, NULL); +} + +void test_cil_copy_block(CuTest *tc) { + char *line[] = {"(", "block", "a", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_block(test_db, test_tree->root->cl_head->cl_head, test_ast_node, 0); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, cil_sym_sizes[CIL_SYM_ARRAY_BLOCK][CIL_SYM_BLOCKS]); + + int rc = cil_copy_block(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_perm(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_class *new_node; + cil_class_init(&new_node); + + struct cil_tree_node *new_tree_node; + cil_tree_node_init(&new_tree_node); + new_tree_node->data = new_node; + new_tree_node->flavor = CIL_CLASS; + + test_ast_node->parent = new_tree_node; + test_ast_node->line = 1; + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_CLASS_SYM_SIZE); + + cil_gen_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head, test_ast_node); + int rc = cil_copy_perm(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + cil_gen_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head->next, test_ast_node); + rc = cil_copy_perm(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + cil_gen_perm(test_db, test_tree->root->cl_head->cl_head->next->next->cl_head->next->next, test_ast_node); + rc = cil_copy_perm(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + +} + +void test_cil_copy_class(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_class(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_CLASS_SYM_SIZE); + + int rc = cil_copy_class(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_common(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_common(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_CLASS_SYM_SIZE); + + int rc = cil_copy_common(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_classcommon(CuTest *tc) { + char *line[] = {"(", "classcommon", "file", "file", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + char *test_key = test_tree->root->cl_head->cl_head->next->data; + struct cil_class *test_cls; + cil_class_init(&test_cls); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_insert(&test_db->symtab[CIL_SYM_CLASSES], (hashtab_key_t)test_key, (struct cil_symtab_datum*)test_cls, test_ast_node); + + test_ast_node->data = test_cls; + test_ast_node->flavor = CIL_CLASS; + + cil_gen_classcommon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_classcommon *test_copy; + cil_classcommon_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_CLASS_SYM_SIZE); + + int rc = cil_copy_classcommon(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_classcommon *)test_ast_node->data)->class_str, test_copy->class_str); + CuAssertStrEquals(tc, ((struct cil_classcommon *)test_ast_node->data)->common_str, test_copy->common_str); +} + +void test_cil_copy_sid(CuTest *tc) { + char *line[] = {"(", "sid", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_sid(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_sid(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_sidcontext(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_sidcontext(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_sidcontext(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_user *)test_copy->data)->datum.name, + ((struct cil_user *)test_ast_node->data)->datum.name); +} + +void test_cil_copy_user(CuTest *tc) { + char *line[] = {"(", "user", "sysadm", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_user(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_user(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_role(CuTest *tc) { + char *line[] = {"(", "role", "role_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_role(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_role(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_userrole(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_userrole(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_userrole *test_copy; + cil_userrole_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_userrole(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_userrole *)test_ast_node->data)->user_str, test_copy->user_str); + CuAssertStrEquals(tc, ((struct cil_userrole *)test_ast_node->data)->role_str, test_copy->role_str); +} + +void test_cil_copy_type(CuTest *tc) { + char *line[] = {"(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_type(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_type(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_typealias(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_typealias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_typealias(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_typeattribute(CuTest *tc) { + char *line[] = {"(", "typettribute", "type_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_typeattribute(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_typeattribute(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_bool(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_bool(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_BOOL); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_bool(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertIntEquals(tc, ((struct cil_bool *)test_copy->data)->value, + ((struct cil_bool *)test_ast_node->data)->value); +} + +void test_cil_copy_type_rule(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_type_rule(test_tree->root->cl_head->cl_head, test_ast_node, CIL_TYPE_TRANSITION); + + struct cil_type_rule *test_copy; + cil_type_rule_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_type_rule(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertIntEquals(tc, ((struct cil_type_rule *)test_ast_node->data)->rule_kind, test_copy->rule_kind); + CuAssertStrEquals(tc, ((struct cil_type_rule *)test_ast_node->data)->src_str, test_copy->src_str); + CuAssertStrEquals(tc, ((struct cil_type_rule *)test_ast_node->data)->tgt_str, test_copy->tgt_str); + CuAssertStrEquals(tc, ((struct cil_type_rule *)test_ast_node->data)->obj_str, test_copy->obj_str); +} + +void test_cil_copy_avrule(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + cil_gen_avrule(test_current, test_ast_node, CIL_AVRULE_ALLOWED); + + struct cil_avrule *test_copy; + cil_avrule_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_avrule(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertIntEquals(tc, ((struct cil_avrule *)test_ast_node->data)->rule_kind, test_copy->rule_kind); + CuAssertStrEquals(tc, ((struct cil_avrule *)test_ast_node->data)->src_str, test_copy->src_str); + CuAssertStrEquals(tc, ((struct cil_avrule *)test_ast_node->data)->tgt_str, test_copy->tgt_str); + CuAssertStrEquals(tc, ((struct cil_avrule *)test_ast_node->data)->classpermset->class_str, test_copy->classpermset->class_str); + CuAssertIntEquals(tc, ((struct cil_avrule *)test_ast_node->data)->classpermset->permset->perms_list_str->head->flavor, test_copy->classpermset->permset->perms_list_str->head->flavor); + CuAssertStrEquals(tc, (char*)((struct cil_avrule *)test_ast_node->data)->classpermset->permset->perms_list_str->head->data, (char*)test_copy->classpermset->permset->perms_list_str->head->data); + CuAssertIntEquals(tc, ((struct cil_avrule *)test_ast_node->data)->classpermset->permset->perms_list_str->head->next->flavor, test_copy->classpermset->permset->perms_list_str->head->next->flavor); + CuAssertStrEquals(tc, (char*)((struct cil_avrule *)test_ast_node->data)->classpermset->permset->perms_list_str->head->next->data, (char*)test_copy->classpermset->permset->perms_list_str->head->next->data); +} + +void test_cil_copy_sens(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_sensitivity(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_sens(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_sensalias(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_sensalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_sensalias(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_sensalias *)test_copy->data)->sens_str, + ((struct cil_sensalias *)test_ast_node->data)->sens_str); +} + +void test_cil_copy_cat(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_category(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_cat(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_catalias(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_catalias(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_catalias(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_catalias *)test_copy->data)->cat_str, + ((struct cil_catalias *)test_ast_node->data)->cat_str); +} + +void test_cil_copy_senscat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_senscat(test_db, test_tree->root->cl_head->next->next->next->next->next->next->cl_head, test_ast_node); + + struct cil_senscat *test_copy; + cil_senscat_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_senscat(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_senscat *)test_ast_node->data)->sens_str, test_copy->sens_str); + CuAssertStrEquals(tc, (char*)((struct cil_senscat *)test_ast_node->data)->catset->cat_list_str->head->data, + (char*)test_copy->catset->cat_list_str->head->data); + CuAssertStrEquals(tc, (char*)((struct cil_senscat *)test_ast_node->data)->catset->cat_list_str->head->next->data, + (char*)test_copy->catset->cat_list_str->head->next->data); +} + +void test_cil_copy_catorder(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_catorder(test_db, test_tree->root->cl_head->next->next->cl_head, test_ast_node); + + struct cil_catorder *test_copy; + cil_catorder_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_catorder(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, (char*)((struct cil_catorder *)test_ast_node->data)->cat_list_str->head->data, (char*)test_copy->cat_list_str->head->data); + CuAssertStrEquals(tc, (char*)((struct cil_catorder *)test_ast_node->data)->cat_list_str->head->next->data, (char*)test_copy->cat_list_str->head->next->data); +} + +void test_cil_copy_dominance(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_dominance(test_db, test_tree->root->cl_head->next->next->next->cl_head, test_ast_node); + + struct cil_sens_dominates *test_copy; + cil_sens_dominates_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_dominance(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, (char*)((struct cil_sens_dominates *)test_ast_node->data)->sens_list_str->head->data, (char*)test_copy->sens_list_str->head->data); + CuAssertStrEquals(tc, (char*)((struct cil_sens_dominates *)test_ast_node->data)->sens_list_str->head->next->data, (char*)test_copy->sens_list_str->head->next->data); +} + +void test_cil_copy_level(CuTest *tc) { + char *line[] = {"(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_level(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_level(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_fill_level(CuTest *tc) { + char *line[] = {"(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_level(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + cil_level_init((struct cil_level**)&test_copy->data); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_fill_level((struct cil_level*)test_ast_node->data, (struct cil_level*)test_copy->data); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_level *)test_copy->data)->sens_str, + ((struct cil_level *)test_ast_node->data)->sens_str); +} + +void test_cil_copy_context(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_context(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_netifcon(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_netifcon *test_copy; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_netifcon(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, test_copy->interface_str, + ((struct cil_netifcon *)test_ast_node->data)->interface_str); + CuAssertStrEquals(tc, test_copy->if_context_str, + ((struct cil_netifcon *)test_ast_node->data)->if_context_str); + CuAssertStrEquals(tc, test_copy->packet_context_str, + ((struct cil_netifcon *)test_ast_node->data)->packet_context_str); +} + +void test_cil_copy_netifcon_nested(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_netifcon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_netifcon *test_copy; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_netifcon(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, test_copy->interface_str, + ((struct cil_netifcon *)test_ast_node->data)->interface_str); + CuAssertStrEquals(tc, test_copy->if_context_str, + ((struct cil_netifcon *)test_ast_node->data)->if_context_str); + CuAssertStrEquals(tc, test_copy->packet_context_str, + ((struct cil_netifcon *)test_ast_node->data)->packet_context_str); + CuAssertStrEquals(tc, test_copy->packet_context->user_str, + ((struct cil_netifcon *)test_ast_node->data)->packet_context->user_str); + CuAssertStrEquals(tc, test_copy->packet_context->role_str, + ((struct cil_netifcon *)test_ast_node->data)->packet_context->role_str); + CuAssertStrEquals(tc, test_copy->packet_context->type_str, + ((struct cil_netifcon *)test_ast_node->data)->packet_context->type_str); + CuAssertStrEquals(tc, test_copy->packet_context->range_str, + ((struct cil_netifcon *)test_ast_node->data)->packet_context->range_str); +} + +void test_cil_copy_fill_context(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "range", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + cil_context_init((struct cil_context**)&test_copy->data); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_fill_context((struct cil_context*)test_ast_node->data, (struct cil_context*)test_copy->data); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->user_str, + ((struct cil_context *)test_ast_node->data)->user_str); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->role_str, + ((struct cil_context *)test_ast_node->data)->role_str); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->type_str, + ((struct cil_context *)test_ast_node->data)->type_str); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->range_str, + ((struct cil_context *)test_ast_node->data)->range_str); +} + +void test_cil_copy_fill_context_anonrange(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_context(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + cil_context_init((struct cil_context**)&test_copy->data); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_fill_context((struct cil_context*)test_ast_node->data, (struct cil_context*)test_copy->data); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->user_str, + ((struct cil_context *)test_ast_node->data)->user_str); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->role_str, + ((struct cil_context *)test_ast_node->data)->role_str); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->type_str, + ((struct cil_context *)test_ast_node->data)->type_str); + CuAssertStrEquals(tc, ((struct cil_context *)test_copy->data)->range_str, + ((struct cil_context *)test_ast_node->data)->range_str); +} + +void test_cil_copy_call(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_call(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_call *test_copy; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_call(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, test_copy->macro_str, ((struct cil_call *)test_ast_node->data)->macro_str); +} + +void test_cil_copy_optional(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_optional(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_optional(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_nodecon(CuTest *tc) { + char *line[] = {"(", "nodecon", "ipaddr", "ipaddr", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_nodecon *test_copy; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_nodecon(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, test_copy->addr_str, + ((struct cil_nodecon *)test_ast_node->data)->addr_str); + CuAssertStrEquals(tc, test_copy->mask_str, + ((struct cil_nodecon *)test_ast_node->data)->mask_str); + CuAssertStrEquals(tc, test_copy->context_str, + ((struct cil_nodecon *)test_ast_node->data)->context_str); +} + +void test_cil_copy_nodecon_anon(CuTest *tc) { + char *line[] = {"(", "nodecon", "(", "192.168.1.1", ")", "(", "192.168.1.1", ")", "(", "user", "role", "type", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_nodecon(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_nodecon *test_copy; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_nodecon(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, test_copy->addr_str, + ((struct cil_nodecon *)test_ast_node->data)->addr_str); + CuAssertStrEquals(tc, test_copy->mask_str, + ((struct cil_nodecon *)test_ast_node->data)->mask_str); + CuAssertStrEquals(tc, test_copy->context_str, + ((struct cil_nodecon *)test_ast_node->data)->context_str); +} + +void test_cil_copy_fill_ipaddr(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + struct cil_ipaddr *new; + cil_ipaddr_init(&new); + struct cil_ipaddr *old; + cil_ipaddr_init(&new); + + old = (struct cil_ipaddr*)test_ast_node->data; + int rc = cil_copy_fill_ipaddr(old, new); + CuAssertIntEquals(tc, rc, SEPOL_OK); + + CuAssertIntEquals(tc, old->family, new->family); +} + +void test_cil_copy_ipaddr(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_ipaddr(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_tree_node *test_copy; + cil_tree_node_init(&test_copy); + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_ipaddr(test_db, test_ast_node->data, &test_copy->data, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_conditional(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_list_item *curr_old; + curr_old = ((struct cil_booleanif*)test_ast_node->data)->expr_stack->head; + + struct cil_conditional *cond_new; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_conditional(test_db, curr_old->data, (void**)&cond_new, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + + CuAssertStrEquals(tc, ((struct cil_conditional*)curr_old->data)->str, cond_new->str); + CuAssertIntEquals(tc, ((struct cil_conditional*)curr_old->data)->flavor, cond_new->flavor); +} + +void test_cil_copy_boolif(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_boolif(test_db, test_tree->root->cl_head->cl_head, test_ast_node); + + struct cil_booleanif *test_copy; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_boolif(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_constrain(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + + struct cil_constrain *test_copy; + + symtab_t sym; + ksu_symtab_init(&sym, CIL_TEST_SYM_SIZE); + + int rc = cil_copy_constrain(test_db, test_ast_node->data, (void**)&test_copy, &sym); + CuAssertIntEquals(tc, rc, SEPOL_OK); + CuAssertStrEquals(tc, ((struct cil_constrain*)test_copy)->classpermset->class_str, ((struct cil_constrain *)test_ast_node->data)->classpermset->class_str); +} +/* +void test_cil_copy_ast(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *test_copy; + cil_constrain_init(&test_copy); + cil_list_init(&test_copy->expr); + + int rc = cil_copy_ast(((struct cil_constrain *)test_ast_node->data)->expr, test_copy->expr); + CuAssertIntEquals(tc, rc, SEPOL_OK); +} + +void test_cil_copy_ast_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_gen_constrain(test_db, test_tree->root->cl_head->cl_head, test_ast_node, CIL_MLSCONSTRAIN); + + struct cil_tree_node *test_current; + test_current = test_tree->root->cl_head->cl_head; + + struct cil_constrain *test_copy; + cil_constrain_init(&test_copy); + cil_list_init(&test_copy->expr); + + int rc = cil_copy_ast(((struct cil_constrain *)test_ast_node->data)->expr, test_copy->expr); + CuAssertIntEquals(tc, rc, SEPOL_ERR); +} +*/ +/* node_helper functions */ + +void test_cil_copy_node_helper_block(CuTest *tc) { + char *line[] = {"(", "block", "a", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_block_merge(CuTest *tc) { + char *line[] = {"(", "block", "a", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_perm(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_class *test_class; + cil_class_init(&test_class); + + struct cil_tree_node *parent_node; + cil_tree_node_init(&parent_node); + parent_node->flavor = CIL_CLASS; + parent_node->data = test_class; + struct cil_tree_node *root; + cil_tree_node_init(&root); + root->flavor = CIL_ROOT; + parent_node->parent = root; + + struct cil_args_copy *extra_args = gen_copy_args(parent_node, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_perm_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_class(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_class_dup_neg(CuTest *tc) { + char *line[] = {"(", "class", "test", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_common(CuTest *tc) { + char *line[] = {"(", "common", "test", "(", "read", "write", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_common_dup_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", "write", "open", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_classcommon(CuTest *tc) { + char *line[] = {"(", "classcommon", "file", "file", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_sid(CuTest *tc) { + char *line[] = {"(", "sid", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_sid_merge(CuTest *tc) { + char *line[] = {"(", "sid", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_sidcontext(CuTest *tc) { + char *line[] = {"(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_user(CuTest *tc) { + char *line[] = {"(", "user", "sysadm", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_user_merge(CuTest *tc) { + char *line[] = {"(", "user", "sysadm", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_role(CuTest *tc) { + char *line[] = {"(", "role", "role_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_role_merge(CuTest *tc) { + char *line[] = {"(", "role", "role_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_userrole(CuTest *tc) { + char *line[] = {"(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_type(CuTest *tc) { + char *line[] = {"(", "type", "type_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_type_merge(CuTest *tc) { + char *line[] = {"(", "type", "type_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_typeattribute(CuTest *tc) { + char *line[] = {"(", "typeattribute", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_typeattribute_merge(CuTest *tc) { + char *line[] = {"(", "typeattribute", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_typealias(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_typealias_dup_neg(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_bool(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_bool_dup_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_avrule(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "file", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_type_rule(CuTest *tc) { + char *line[] = {"(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_sens(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_sens_merge(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_sensalias(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_sensalias_dup_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_cat(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_cat_merge(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_catalias(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_catalias_dup_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_senscat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_senscat *test_senscat; + cil_senscat_init(&test_senscat); + + struct cil_tree_node *parent_node; + cil_tree_node_init(&parent_node); + parent_node->flavor = CIL_SENSCAT; + parent_node->data = test_senscat; + + struct cil_args_copy *extra_args = gen_copy_args(parent_node, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_catorder(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_catorder *test_catorder; + cil_catorder_init(&test_catorder); + + struct cil_tree_node *parent_node; + cil_tree_node_init(&parent_node); + parent_node->flavor = CIL_CATORDER; + parent_node->data = test_catorder; + + struct cil_args_copy *extra_args = gen_copy_args(parent_node, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head->next->next, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_dominance(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_sens *test_sens; + cil_sens_init(&test_sens); + + struct cil_tree_node *parent_node; + cil_tree_node_init(&parent_node); + parent_node->flavor = CIL_SENS; + parent_node->data = test_sens; + + struct cil_args_copy *extra_args = gen_copy_args(parent_node, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_level(CuTest *tc) { + char *line[] = {"(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_level_dup_neg(CuTest *tc) { + char *line[] = {"(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_context(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_context_dup_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_netifcon(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_call(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_optional(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_optional_merge(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_ipaddr(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_ipaddr_dup_neg(CuTest *tc) { + char *line[] = {"(", "ipaddr", "ip", "192.168.1.1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db->ast->root, test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_boolif(CuTest *tc) { + char *line[] = {"(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_mlsconstrain(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l1", "l2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, finished, 0); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_copy_node_helper_orignull_neg(CuTest *tc) { + char *line[] = {"(", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + uint32_t finished = 0; + + struct cil_args_copy *extra_args = gen_copy_args(test_db2->ast->root, test_db2); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_copy_node_helper_extraargsnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "l1", "l2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_db *test_db2; + cil_db_init(&test_db2); + + struct cil_args_copy *extra_args = NULL; + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_copy_node_helper(test_db->ast->root->cl_head, &finished, extra_args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} diff --git a/kernel/libsepol/cil/test/unit/test_cil_copy_ast.h b/kernel/libsepol/cil/test/unit/test_cil_copy_ast.h new file mode 100644 index 00000000..b1aace12 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_copy_ast.h @@ -0,0 +1,176 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_COPY_AST_H_ +#define TEST_CIL_COPY_AST_H_ + +#include "CuTest.h" + +void test_cil_copy_list(CuTest *); +void test_cil_copy_list_sublist(CuTest *); +void test_cil_copy_list_sublist_extra(CuTest *); +void test_cil_copy_list_orignull_neg(CuTest *); + +void test_cil_copy_block(CuTest *); +void test_cil_copy_node_helper_block(CuTest *tc); +void test_cil_copy_node_helper_block_merge(CuTest *tc); + +void test_cil_copy_perm(CuTest *); +void test_cil_copy_node_helper_perm(CuTest *tc); +void test_cil_copy_node_helper_perm_neg(CuTest *tc); + +void test_cil_copy_class(CuTest *); +void test_cil_copy_node_helper_class(CuTest *tc); +void test_cil_copy_node_helper_class_dup_neg(CuTest *tc); + +void test_cil_copy_common(CuTest *); +void test_cil_copy_node_helper_common(CuTest *tc); +void test_cil_copy_node_helper_common_dup_neg(CuTest *tc); + +void test_cil_copy_classcommon(CuTest *); +void test_cil_copy_node_helper_classcommon(CuTest *tc); + +void test_cil_copy_sid(CuTest *); +void test_cil_copy_node_helper_sid(CuTest *tc); +void test_cil_copy_node_helper_sid_merge(CuTest *tc); + +void test_cil_copy_sidcontext(CuTest *); +void test_cil_copy_node_helper_sidcontext(CuTest *tc); + +void test_cil_copy_user(CuTest *); +void test_cil_copy_node_helper_user(CuTest *tc); +void test_cil_copy_node_helper_user_merge(CuTest *tc); + +void test_cil_copy_role(CuTest *); +void test_cil_copy_node_helper_role(CuTest *tc); +void test_cil_copy_node_helper_role_merge(CuTest *tc); + +void test_cil_copy_userrole(CuTest *); +void test_cil_copy_node_helper_userrole(CuTest *tc); + +void test_cil_copy_type(CuTest *); +void test_cil_copy_node_helper_type(CuTest *tc); +void test_cil_copy_node_helper_type_merge(CuTest *tc); + +void test_cil_copy_typeattribute(CuTest *); +void test_cil_copy_node_helper_typeattribute(CuTest *tc); +void test_cil_copy_node_helper_typeattribute_merge(CuTest *tc); + +void test_cil_copy_typealias(CuTest *); +void test_cil_copy_node_helper_typealias(CuTest *tc); +void test_cil_copy_node_helper_typealias_dup_neg(CuTest *tc); + +void test_cil_copy_bool(CuTest *); +void test_cil_copy_node_helper_bool(CuTest *tc); +void test_cil_copy_node_helper_bool_dup_neg(CuTest *tc); + +void test_cil_copy_avrule(CuTest *); +void test_cil_copy_node_helper_avrule(CuTest *tc); + +void test_cil_copy_type_rule(CuTest *); +void test_cil_copy_node_helper_type_rule(CuTest *tc); + +void test_cil_copy_sens(CuTest *); +void test_cil_copy_node_helper_sens(CuTest *tc); +void test_cil_copy_node_helper_sens_merge(CuTest *tc); + +void test_cil_copy_sensalias(CuTest *); +void test_cil_copy_node_helper_sensalias(CuTest *tc); +void test_cil_copy_node_helper_sensalias_dup_neg(CuTest *tc); + +void test_cil_copy_cat(CuTest *); +void test_cil_copy_node_helper_cat(CuTest *tc); +void test_cil_copy_node_helper_cat_merge(CuTest *tc); + +void test_cil_copy_catalias(CuTest *); +void test_cil_copy_node_helper_catalias(CuTest *tc); +void test_cil_copy_node_helper_catalias_dup_neg(CuTest *tc); + +void test_cil_copy_senscat(CuTest *); +void test_cil_copy_node_helper_senscat(CuTest *tc); + +void test_cil_copy_catorder(CuTest *); +void test_cil_copy_node_helper_catorder(CuTest *tc); + +void test_cil_copy_dominance(CuTest *); +void test_cil_copy_node_helper_dominance(CuTest *tc); + +void test_cil_copy_level(CuTest *); +void test_cil_copy_node_helper_level(CuTest *tc); +void test_cil_copy_node_helper_level_dup_neg(CuTest *tc); + +void test_cil_copy_fill_level(CuTest *); + +void test_cil_copy_context(CuTest *); +void test_cil_copy_node_helper_context(CuTest *tc); +void test_cil_copy_node_helper_context_dup_neg(CuTest *tc); + +void test_cil_copy_netifcon(CuTest *); +void test_cil_copy_netifcon_nested(CuTest *); +void test_cil_copy_node_helper_netifcon(CuTest *tc); +void test_cil_copy_node_helper_netifcon_merge(CuTest *tc); + +void test_cil_copy_fill_context(CuTest *); +void test_cil_copy_fill_context_anonrange(CuTest *); + +void test_cil_copy_call(CuTest *); +void test_cil_copy_node_helper_call(CuTest *tc); + +void test_cil_copy_optional(CuTest *); +void test_cil_copy_node_helper_optional(CuTest *tc); +void test_cil_copy_node_helper_optional_merge(CuTest *tc); + +void test_cil_copy_nodecon(CuTest *); +void test_cil_copy_nodecon_anon(CuTest *); + +void test_cil_copy_fill_ipaddr(CuTest *); + +void test_cil_copy_ipaddr(CuTest *); +void test_cil_copy_node_helper_ipaddr(CuTest *tc); +void test_cil_copy_node_helper_ipaddr_dup_neg(CuTest *tc); + +void test_cil_copy_conditional(CuTest *); + +void test_cil_copy_boolif(CuTest *); +void test_cil_copy_node_helper_boolif(CuTest *tc); + +void test_cil_copy_constrain(CuTest *); +void test_cil_copy_node_helper_mlsconstrain(CuTest *tc); + +void test_cil_copy_ast(CuTest *); +void test_cil_copy_ast_neg(CuTest *); + +void test_cil_copy_node_helper_orignull_neg(CuTest *tc); +void test_cil_copy_node_helper_extraargsnull_neg(CuTest *tc); + +void test_cil_copy_data_helper(CuTest *tc); +void test_cil_copy_data_helper_getparentsymtab_neg(CuTest *tc); +void test_cil_copy_data_helper_duplicatedb_neg(CuTest *tc); + +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_fqn.c b/kernel/libsepol/cil/test/unit/test_cil_fqn.c new file mode 100644 index 00000000..4304fc1d --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_fqn.c @@ -0,0 +1,75 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "CilTest.h" + +#include "../../src/cil_fqn.h" +#include "../../src/cil_build_ast.h" + +void test_cil_qualify_name(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "context", "con", "(", "blah_u", "blah_r", "blah_t", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", + "(", "sid", "test", "con", NULL}; + + struct cil_tree *tree; + gen_test_tree(&tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, tree->root, test_db->ast->root); + + int rc = cil_fqn_qualify(test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_qualify_name_cil_flavor(CuTest *tc) { + char *line[] = {"(", "class", "file", "inherits", "file", + "(", "open", ")", ")", NULL}; + + struct cil_tree *tree; + gen_test_tree(&tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, tree->root, test_db->ast->root); + + int rc = cil_fqn_qualify(test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} diff --git a/kernel/libsepol/cil/test/unit/test_cil_fqn.h b/kernel/libsepol/cil/test/unit/test_cil_fqn.h new file mode 100644 index 00000000..93f0ffd5 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_fqn.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_FQN_H_ +#define TEST_CIL_FQN_H_ + +#include "CuTest.h" + +void test_cil_qualify_name(CuTest *); +void test_cil_qualify_name_cil_flavor(CuTest *tc); +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_lexer.c b/kernel/libsepol/cil/test/unit/test_cil_lexer.c new file mode 100644 index 00000000..011afeff --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_lexer.c @@ -0,0 +1,100 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "test_cil_lexer.h" + +#include "../../src/cil_lexer.h" + +void test_cil_lexer_setup(CuTest *tc) { + char *test_str = "(test \"qstring\");comment\n"; + uint32_t str_size = strlen(test_str); + char *buffer = malloc(str_size + 2); + + memset(buffer+str_size, 0, 2); + strncpy(buffer, test_str, str_size); + + int rc = cil_lexer_setup(buffer, str_size + 2); + CuAssertIntEquals(tc, SEPOL_OK, rc); + + free(buffer); +} + +void test_cil_lexer_next(CuTest *tc) { + char *test_str = "(test \"qstring\") ;comment\n"; + uint32_t str_size = strlen(test_str); + char *buffer = malloc(str_size + 2); + + memset(buffer+str_size, 0, 2); + strcpy(buffer, test_str); + + cil_lexer_setup(buffer, str_size + 2); + + struct token test_tok; + + int rc = cil_lexer_next(&test_tok); + CuAssertIntEquals(tc, SEPOL_OK, rc); + + CuAssertIntEquals(tc, OPAREN, test_tok.type); + CuAssertStrEquals(tc, "(", test_tok.value); + CuAssertIntEquals(tc, 1, test_tok.line); + + rc = cil_lexer_next(&test_tok); + CuAssertIntEquals(tc, SEPOL_OK, rc); + + CuAssertIntEquals(tc, SYMBOL, test_tok.type); + CuAssertStrEquals(tc, "test", test_tok.value); + CuAssertIntEquals(tc, 1, test_tok.line); + + rc = cil_lexer_next(&test_tok); + CuAssertIntEquals(tc, SEPOL_OK, rc); + + CuAssertIntEquals(tc, QSTRING, test_tok.type); + CuAssertStrEquals(tc, "\"qstring\"", test_tok.value); + CuAssertIntEquals(tc, 1, test_tok.line); + + rc = cil_lexer_next(&test_tok); + CuAssertIntEquals(tc, SEPOL_OK, rc); + + CuAssertIntEquals(tc, CPAREN, test_tok.type); + CuAssertStrEquals(tc, ")", test_tok.value); + CuAssertIntEquals(tc, 1, test_tok.line); + + rc = cil_lexer_next(&test_tok); + CuAssertIntEquals(tc, SEPOL_OK, rc); + + CuAssertIntEquals(tc, COMMENT, test_tok.type); + CuAssertStrEquals(tc, ";comment", test_tok.value); + CuAssertIntEquals(tc, 1, test_tok.line); + + free(buffer); +} + diff --git a/kernel/libsepol/cil/test/unit/test_cil_lexer.h b/kernel/libsepol/cil/test/unit/test_cil_lexer.h new file mode 100644 index 00000000..78a46098 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_lexer.h @@ -0,0 +1,38 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_LEXER_H_ +#define TEST_CIL_LEXER_H_ + +#include "CuTest.h" + +void test_cil_lexer_setup(CuTest *); +void test_cil_lexer_next(CuTest *); + +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_list.c b/kernel/libsepol/cil/test/unit/test_cil_list.c new file mode 100644 index 00000000..b7a63afa --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_list.c @@ -0,0 +1,345 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include "CuTest.h" +#include "CilTest.h" + +#include "../../src/cil_internal.h" +#include "../../src/cil_build_ast.h" + +void test_cil_list_init(CuTest *tc) { + struct cil_avrule *test_avrule = malloc(sizeof(*test_avrule)); + + cil_classpermset_init(&test_avrule->classpermset); + cil_permset_init(&test_avrule->classpermset->permset); + + cil_list_init(&test_avrule->classpermset->permset->perms_list_str); + CuAssertPtrNotNull(tc, test_avrule->classpermset->permset->perms_list_str); + + cil_destroy_avrule(test_avrule); +} + +void test_cil_list_append_item(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + int rc = cil_list_append_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_list_append_item_append(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + int rc = cil_list_append_item(test_class_list, test_new_item); + + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head->next; + + int rc2 = cil_list_append_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); +} + +void test_cil_list_append_item_append_extra(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", "process", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + int rc = cil_list_append_item(test_class_list, test_new_item); + + cil_list_item_init(&test_new_item); + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head->next; + + int rc2 = cil_list_append_item(test_class_list, test_new_item); + + cil_list_item_init(&test_new_item); + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head->next->next; + + int rc3 = cil_list_append_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_list_append_item_listnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list = NULL; + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + int rc = cil_list_append_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_list_append_item_itemnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item = NULL; + + int rc = cil_list_append_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_list_prepend_item(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + int rc = cil_list_prepend_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_list_prepend_item_prepend(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + int rc = cil_list_prepend_item(test_class_list, test_new_item); + + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_list_prepend_item_prepend_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", "process", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + struct cil_list_item *test_new_item_next; + cil_list_item_init(&test_new_item_next); + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head->next; + test_new_item->next = test_new_item_next; + + int rc = cil_list_prepend_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_list_prepend_item_listnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list = NULL; + + struct cil_list_item *test_new_item; + cil_list_item_init(&test_new_item); + + test_new_item->flavor = CIL_CLASS; + test_new_item->data = test_tree->root->cl_head->cl_head->next->cl_head; + + int rc = cil_list_prepend_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_list_prepend_item_itemnull_neg(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "dir", ")", "(", "create", "relabelto", ")", "(", "eq", "12", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + struct cil_list *test_class_list; + cil_list_init(&test_class_list); + + struct cil_list_item *test_new_item = NULL; + + int rc = cil_list_prepend_item(test_class_list, test_new_item); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} diff --git a/kernel/libsepol/cil/test/unit/test_cil_list.h b/kernel/libsepol/cil/test/unit/test_cil_list.h new file mode 100644 index 00000000..e6276835 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_list.h @@ -0,0 +1,46 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_LIST_H_ +#define TEST_CIL_LIST_H_ + +#include "CuTest.h" + +void test_cil_list_item_init(CuTest *); +void test_cil_list_append_item(CuTest *); +void test_cil_list_append_item_append(CuTest *); +void test_cil_list_append_item_append_extra(CuTest *); +void test_cil_list_append_item_listnull_neg(CuTest *); +void test_cil_list_append_item_itemnull_neg(CuTest *); +void test_cil_list_prepend_item_prepend(CuTest *); +void test_cil_list_prepend_item_prepend_neg(CuTest *); +void test_cil_list_prepend_item_listnull_neg(CuTest *); +void test_cil_list_prepend_item_itemnull_neg(CuTest *); + +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_parser.c b/kernel/libsepol/cil/test/unit/test_cil_parser.c new file mode 100644 index 00000000..43dc305e --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_parser.c @@ -0,0 +1,57 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "CilTest.h" +#include "test_cil_parser.h" + +#include "../../src/cil_parser.h" +#include "../../src/cil_internal.h" + +// TODO rewrite to use the gen_tree function +void test_cil_parser(CuTest *tc) { + int rc = 0; + struct cil_file_data *data; + + struct cil_tree *test_parse_root; + cil_tree_init(&test_parse_root); + + struct cil_db *test_db; + cil_db_init(&test_db); + + set_cil_file_data(&data); + + rc = cil_parser("policy.cil", data->buffer, data->file_size + 2, &test_parse_root); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_parse_root); + // TODO add checking of the parse tree that is returned +} + diff --git a/kernel/libsepol/cil/test/unit/test_cil_parser.h b/kernel/libsepol/cil/test/unit/test_cil_parser.h new file mode 100644 index 00000000..2cb280da --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_parser.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_PARSER_H_ +#define TEST_CIL_PARSER_H_ + +#include "CuTest.h" + +void test_cil_parser(CuTest *); + +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_post.c b/kernel/libsepol/cil/test/unit/test_cil_post.c new file mode 100644 index 00000000..8bb7e764 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_post.c @@ -0,0 +1,703 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "CilTest.h" +#include "test_cil_post.h" + +#include "../../src/cil_post.h" +#include "../../src/cil_internal.h" + +void test_cil_post_filecon_compare_meta_a_not_b(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = "ba.r"; + afilecon->path_str = "foo"; + + bfilecon->root_str = "barr"; + bfilecon->path_str = "foo"; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_filecon_compare_meta_b_not_a(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = "bar"; + afilecon->path_str = "foo"; + + bfilecon->root_str = "ba.rr"; + bfilecon->path_str = "foo"; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_filecon_compare_meta_a_and_b_strlen_a_greater_b(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = ".\\$"; + afilecon->path_str = ".$({"; + + bfilecon->root_str = ".?"; + bfilecon->path_str = "."; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_filecon_compare_type_atype_greater_btype(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = ".\\$"; + afilecon->path_str = ".$({"; + afilecon->type = CIL_FILECON_CHAR; + + bfilecon->root_str = ".\\$"; + bfilecon->path_str = ".$({"; + bfilecon->type = CIL_FILECON_DIR; + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_filecon_compare_type_btype_greater_atype(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = ".\\$"; + afilecon->path_str = ".$({"; + afilecon->type = CIL_FILECON_DIR; + + bfilecon->root_str = ".\\$"; + bfilecon->path_str = ".$({"; + bfilecon->type = CIL_FILECON_CHAR; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_filecon_compare_meta_a_and_b_strlen_b_greater_a(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = "."; + afilecon->path_str = "."; + + bfilecon->root_str = ".*+|[({"; + bfilecon->path_str = "."; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_filecon_compare_stemlen_a_greater_b(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = "bar"; + afilecon->path_str = "foo"; + + bfilecon->root_str = "barr"; + bfilecon->path_str = "foo"; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_filecon_compare_stemlen_b_greater_a(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = "barre"; + afilecon->path_str = "foo"; + + bfilecon->root_str = "barr"; + bfilecon->path_str = "foo"; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_filecon_compare_equal(CuTest *tc) { + struct cil_filecon *afilecon; + cil_filecon_init(&afilecon); + + struct cil_filecon *bfilecon; + cil_filecon_init(&bfilecon); + + afilecon->root_str = ".\\$"; + afilecon->path_str = ".$({"; + afilecon->type = CIL_FILECON_DIR; + + bfilecon->root_str = ".\\$"; + bfilecon->path_str = ".$({"; + bfilecon->type = CIL_FILECON_DIR; + + + int rc = cil_post_filecon_compare(&afilecon, &bfilecon); + CuAssertIntEquals(tc, 0, rc); +} + +void test_cil_post_portcon_compare_atotal_greater_btotal(CuTest *tc) { + struct cil_portcon *aportcon; + cil_portcon_init(&aportcon); + + struct cil_portcon *bportcon; + cil_portcon_init(&bportcon); + + aportcon->port_low = 15; + aportcon->port_high = 30; + + bportcon->port_low = 10; + bportcon->port_high = 11; + + int rc = cil_post_portcon_compare(&aportcon, &bportcon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_portcon_compare_btotal_greater_atotal(CuTest *tc) { + struct cil_portcon *aportcon; + cil_portcon_init(&aportcon); + + struct cil_portcon *bportcon; + cil_portcon_init(&bportcon); + + aportcon->port_low = 5; + aportcon->port_high = 5; + + bportcon->port_low = 11; + bportcon->port_high = 20; + + int rc = cil_post_portcon_compare(&aportcon, &bportcon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_portcon_compare_aportlow_greater_bportlow(CuTest *tc) { + struct cil_portcon *aportcon; + cil_portcon_init(&aportcon); + + struct cil_portcon *bportcon; + cil_portcon_init(&bportcon); + + aportcon->port_low = 30; + aportcon->port_high = 33; + + bportcon->port_low = 17; + bportcon->port_high = 20; + + int rc = cil_post_portcon_compare(&aportcon, &bportcon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_portcon_compare_bportlow_greater_aportlow(CuTest *tc) { + struct cil_portcon *aportcon; + cil_portcon_init(&aportcon); + + struct cil_portcon *bportcon; + cil_portcon_init(&bportcon); + + aportcon->port_low = 5; + aportcon->port_high = 8; + + bportcon->port_low = 17; + bportcon->port_high = 20; + + int rc = cil_post_portcon_compare(&aportcon, &bportcon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_portcon_compare_equal(CuTest *tc) { + struct cil_portcon *aportcon; + cil_portcon_init(&aportcon); + + struct cil_portcon *bportcon; + cil_portcon_init(&bportcon); + + aportcon->port_low = 17; + aportcon->port_high = 20; + + bportcon->port_low = 17; + bportcon->port_high = 20; + + int rc = cil_post_portcon_compare(&aportcon, &bportcon); + CuAssertTrue(tc, rc == 0); +} + +void test_cil_post_genfscon_compare_atypestr_greater_btypestr(CuTest *tc) { + struct cil_genfscon *agenfscon; + cil_genfscon_init(&agenfscon); + agenfscon->fs_str = "aaaa"; + + struct cil_genfscon *bgenfscon; + cil_genfscon_init(&bgenfscon); + bgenfscon->fs_str = "bbbb"; + + int rc = cil_post_genfscon_compare(&agenfscon, &bgenfscon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_genfscon_compare_btypestr_greater_atypestr(CuTest *tc) { + struct cil_genfscon *agenfscon; + cil_genfscon_init(&agenfscon); + agenfscon->fs_str = "bbbb"; + + struct cil_genfscon *bgenfscon; + cil_genfscon_init(&bgenfscon); + bgenfscon->fs_str = "aaaa"; + + int rc = cil_post_genfscon_compare(&agenfscon, &bgenfscon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_genfscon_compare_apathstr_greater_bpathstr(CuTest *tc) { + struct cil_genfscon *agenfscon; + cil_genfscon_init(&agenfscon); + agenfscon->fs_str = "aaaa"; + agenfscon->path_str = "ff"; + + struct cil_genfscon *bgenfscon; + cil_genfscon_init(&bgenfscon); + bgenfscon->fs_str = "aaaa"; + bgenfscon->path_str = "gg"; + + int rc = cil_post_genfscon_compare(&agenfscon, &bgenfscon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_genfscon_compare_bpathstr_greater_apathstr(CuTest *tc) { + struct cil_genfscon *agenfscon; + cil_genfscon_init(&agenfscon); + agenfscon->fs_str = "bbbb"; + agenfscon->path_str = "cccc"; + + struct cil_genfscon *bgenfscon; + cil_genfscon_init(&bgenfscon); + bgenfscon->fs_str = "bbbb"; + bgenfscon->path_str = "aaaa"; + + int rc = cil_post_genfscon_compare(&agenfscon, &bgenfscon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_genfscon_compare_equal(CuTest *tc) { + struct cil_genfscon *agenfscon; + cil_genfscon_init(&agenfscon); + agenfscon->fs_str = "bbbb"; + agenfscon->path_str = "cccc"; + + struct cil_genfscon *bgenfscon; + cil_genfscon_init(&bgenfscon); + bgenfscon->fs_str = "bbbb"; + bgenfscon->path_str = "cccc"; + + int rc = cil_post_genfscon_compare(&agenfscon, &bgenfscon); + CuAssertIntEquals(tc, 0, rc); +} + +void test_cil_post_netifcon_compare_a_greater_b(CuTest *tc) { + struct cil_netifcon *anetifcon; + cil_netifcon_init(&anetifcon); + anetifcon->interface_str = "aaa"; + + struct cil_netifcon *bnetifcon; + cil_netifcon_init(&bnetifcon); + bnetifcon->interface_str = "bbb"; + + int rc = cil_post_netifcon_compare(&anetifcon, &bnetifcon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_netifcon_compare_b_greater_a(CuTest *tc) { + struct cil_netifcon *anetifcon; + cil_netifcon_init(&anetifcon); + anetifcon->interface_str = "bbb"; + + struct cil_netifcon *bnetifcon; + cil_netifcon_init(&bnetifcon); + bnetifcon->interface_str = "aaa"; + + int rc = cil_post_netifcon_compare(&anetifcon, &bnetifcon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_netifcon_compare_equal(CuTest *tc) { + struct cil_netifcon *anetifcon; + cil_netifcon_init(&anetifcon); + anetifcon->interface_str = "aaa"; + + struct cil_netifcon *bnetifcon; + cil_netifcon_init(&bnetifcon); + bnetifcon->interface_str = "aaa"; + + int rc = cil_post_netifcon_compare(&anetifcon, &bnetifcon); + CuAssertTrue(tc, rc == 0); +} + +void test_cil_post_nodecon_compare_aipv4_bipv6(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v4.s_addr = 103; + anodecon->mask->ip.v4.s_addr = 100; + anodecon->addr->family = AF_INET; + + bnodecon->addr->ip.v4.s_addr = 100; + bnodecon->mask->ip.v4.s_addr = 100; + bnodecon->addr->family = AF_INET6; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_nodecon_compare_aipv6_bipv4(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v4.s_addr = 103; + anodecon->mask->ip.v4.s_addr = 100; + anodecon->addr->family = AF_INET6; + + bnodecon->addr->ip.v4.s_addr = 100; + bnodecon->mask->ip.v4.s_addr = 100; + bnodecon->addr->family = AF_INET; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_nodecon_compare_aipv4_greaterthan_bipv4(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v4.s_addr = 103; + anodecon->mask->ip.v4.s_addr = 100; + anodecon->addr->family = AF_INET; + + bnodecon->addr->ip.v4.s_addr = 100; + bnodecon->mask->ip.v4.s_addr = 100; + bnodecon->addr->family = AF_INET; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_nodecon_compare_aipv4_lessthan_bipv4(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v4.s_addr = 99; + anodecon->mask->ip.v4.s_addr = 100; + anodecon->addr->family = AF_INET; + + bnodecon->addr->ip.v4.s_addr = 100; + bnodecon->mask->ip.v4.s_addr = 100; + bnodecon->addr->family = AF_INET; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_nodecon_compare_amaskipv4_greaterthan_bmaskipv4(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v4.s_addr = 103; + anodecon->mask->ip.v4.s_addr = 101; + anodecon->addr->family = AF_INET; + + bnodecon->addr->ip.v4.s_addr = 100; + bnodecon->mask->ip.v4.s_addr = 100; + bnodecon->addr->family = AF_INET; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_nodecon_compare_amaskipv4_lessthan_bmaskipv4(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v4.s_addr = 99; + anodecon->mask->ip.v4.s_addr = 99; + anodecon->addr->family = AF_INET; + + bnodecon->addr->ip.v4.s_addr = 100; + bnodecon->mask->ip.v4.s_addr = 100; + bnodecon->addr->family = AF_INET; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_nodecon_compare_aipv6_greaterthan_bipv6(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v6.s6_addr[0] = '5'; + anodecon->mask->ip.v6.s6_addr[0] = '9'; + anodecon->addr->family = AF_INET6; + + bnodecon->addr->ip.v6.s6_addr[0] = '3'; + bnodecon->mask->ip.v6.s6_addr[0] = '9'; + bnodecon->addr->family = AF_INET6; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_nodecon_compare_aipv6_lessthan_bipv6(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v6.s6_addr[0] = '3'; + anodecon->mask->ip.v6.s6_addr[0] = '1'; + anodecon->addr->family = AF_INET6; + + bnodecon->addr->ip.v6.s6_addr[0] = '5'; + bnodecon->mask->ip.v6.s6_addr[0] = '1'; + bnodecon->addr->family = AF_INET6; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_nodecon_compare_amaskipv6_greaterthan_bmaskipv6(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v6.s6_addr[0] = '1'; + anodecon->mask->ip.v6.s6_addr[0] = '4'; + anodecon->addr->family = AF_INET6; + + bnodecon->addr->ip.v6.s6_addr[0] = '1'; + bnodecon->mask->ip.v6.s6_addr[0] = '3'; + bnodecon->addr->family = AF_INET6; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_nodecon_compare_amaskipv6_lessthan_bmaskipv6(CuTest *tc) { + struct cil_nodecon *anodecon; + cil_nodecon_init(&anodecon); + cil_ipaddr_init(&anodecon->addr); + cil_ipaddr_init(&anodecon->mask); + + struct cil_nodecon *bnodecon; + cil_nodecon_init(&bnodecon); + cil_ipaddr_init(&bnodecon->addr); + cil_ipaddr_init(&bnodecon->mask); + + anodecon->addr->ip.v6.s6_addr[0] = '5'; + anodecon->mask->ip.v6.s6_addr[0] = '1'; + anodecon->addr->family = AF_INET6; + + bnodecon->addr->ip.v6.s6_addr[0] = '5'; + bnodecon->mask->ip.v6.s6_addr[0] = '6'; + bnodecon->addr->family = AF_INET6; + + int rc = cil_post_nodecon_compare(&anodecon, &bnodecon); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_fsuse_compare_type_a_greater_b(CuTest *tc) { + struct cil_fsuse *afsuse; + cil_fsuse_init(&afsuse); + afsuse->type = CIL_FSUSE_XATTR; + + struct cil_fsuse *bfsuse; + cil_fsuse_init(&bfsuse); + bfsuse->type = CIL_FSUSE_TASK; + + int rc = cil_post_fsuse_compare(&afsuse, &bfsuse); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_fsuse_compare_type_b_greater_a(CuTest *tc) { + struct cil_fsuse *afsuse; + cil_fsuse_init(&afsuse); + afsuse->type = CIL_FSUSE_TASK; + + struct cil_fsuse *bfsuse; + cil_fsuse_init(&bfsuse); + bfsuse->type = CIL_FSUSE_XATTR; + + int rc = cil_post_fsuse_compare(&afsuse, &bfsuse); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_fsuse_compare_fsstr_a_greater_b(CuTest *tc) { + struct cil_fsuse *afsuse; + cil_fsuse_init(&afsuse); + afsuse->type = CIL_FSUSE_XATTR; + afsuse->fs_str = "aaa"; + + struct cil_fsuse *bfsuse; + cil_fsuse_init(&bfsuse); + bfsuse->type = CIL_FSUSE_XATTR; + bfsuse->fs_str = "bbb"; + + int rc = cil_post_fsuse_compare(&afsuse, &bfsuse); + CuAssertTrue(tc, rc < 0); +} + +void test_cil_post_fsuse_compare_fsstr_b_greater_a(CuTest *tc) { + struct cil_fsuse *afsuse; + cil_fsuse_init(&afsuse); + afsuse->type = CIL_FSUSE_XATTR; + afsuse->fs_str = "bbb"; + + struct cil_fsuse *bfsuse; + cil_fsuse_init(&bfsuse); + bfsuse->type = CIL_FSUSE_XATTR; + bfsuse->fs_str = "aaa"; + + int rc = cil_post_fsuse_compare(&afsuse, &bfsuse); + CuAssertTrue(tc, rc > 0); +} + +void test_cil_post_fsuse_compare_equal(CuTest *tc) { + struct cil_fsuse *afsuse; + cil_fsuse_init(&afsuse); + afsuse->type = CIL_FSUSE_XATTR; + afsuse->fs_str = "foo"; + + struct cil_fsuse *bfsuse; + cil_fsuse_init(&bfsuse); + bfsuse->type = CIL_FSUSE_XATTR; + bfsuse->fs_str = "foo"; + + int rc = cil_post_fsuse_compare(&afsuse, &bfsuse); + CuAssertTrue(tc, rc == 0); +} + + + diff --git a/kernel/libsepol/cil/test/unit/test_cil_post.h b/kernel/libsepol/cil/test/unit/test_cil_post.h new file mode 100644 index 00000000..b3c16a35 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_post.h @@ -0,0 +1,79 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_POLICY_H_ +#define TEST_CIL_POLICY_H_ + +#include "CuTest.h" + +void test_cil_post_filecon_compare_meta_a_not_b(CuTest *tc); +void test_cil_post_filecon_compare_meta_b_not_a(CuTest *tc); +void test_cil_post_filecon_compare_meta_a_and_b_strlen_a_greater_b(CuTest *tc); +void test_cil_post_filecon_compare_meta_a_and_b_strlen_b_greater_a(CuTest *tc); +void test_cil_post_filecon_compare_type_atype_greater_btype(CuTest *tc); +void test_cil_post_filecon_compare_type_btype_greater_atype(CuTest *tc); +void test_cil_post_filecon_compare_stemlen_a_greater_b(CuTest *tc); +void test_cil_post_filecon_compare_stemlen_b_greater_a(CuTest *tc); +void test_cil_post_filecon_compare_equal(CuTest *tc); + +void test_cil_post_portcon_compare_atotal_greater_btotal(CuTest *tc); +void test_cil_post_portcon_compare_btotal_greater_atotal(CuTest *tc); +void test_cil_post_portcon_compare_aportlow_greater_bportlow(CuTest *tc); +void test_cil_post_portcon_compare_bportlow_greater_aportlow(CuTest *tc); +void test_cil_post_portcon_compare_equal(CuTest *tc); + +void test_cil_post_genfscon_compare_atypestr_greater_btypestr(CuTest *tc); +void test_cil_post_genfscon_compare_btypestr_greater_atypestr(CuTest *tc); +void test_cil_post_genfscon_compare_apathstr_greater_bpathstr(CuTest *tc); +void test_cil_post_genfscon_compare_bpathstr_greater_apathstr(CuTest *tc); +void test_cil_post_genfscon_compare_equal(CuTest *tc); + +void test_cil_post_netifcon_compare_a_greater_b(CuTest *tc); +void test_cil_post_netifcon_compare_b_greater_a(CuTest *tc); +void test_cil_post_netifcon_compare_equal(CuTest *tc); + +void test_cil_post_nodecon_compare_aipv4_bipv6(CuTest *tc); +void test_cil_post_nodecon_compare_aipv6_bipv4(CuTest *tc); +void test_cil_post_nodecon_compare_aipv4_greaterthan_bipv4(CuTest *tc); +void test_cil_post_nodecon_compare_aipv4_lessthan_bipv4(CuTest *tc); +void test_cil_post_nodecon_compare_amaskipv4_greaterthan_bmaskipv4(CuTest *tc); +void test_cil_post_nodecon_compare_amaskipv4_lessthan_bmaskipv4(CuTest *tc); +void test_cil_post_nodecon_compare_aipv6_greaterthan_bipv6(CuTest *tc); +void test_cil_post_nodecon_compare_aipv6_lessthan_bipv6(CuTest *tc); +void test_cil_post_nodecon_compare_amaskipv6_greaterthan_bmaskipv6(CuTest *tc); +void test_cil_post_nodecon_compare_amaskipv6_lessthan_bmaskipv6(CuTest *tc); + +void test_cil_post_fsuse_compare_type_a_greater_b(CuTest *tc); +void test_cil_post_fsuse_compare_type_b_greater_a(CuTest *tc); +void test_cil_post_fsuse_compare_fsstr_a_greater_b(CuTest *tc); +void test_cil_post_fsuse_compare_fsstr_b_greater_a(CuTest *tc); +void test_cil_post_fsuse_compare_equal(CuTest *tc); + +#endif + diff --git a/kernel/libsepol/cil/test/unit/test_cil_resolve_ast.c b/kernel/libsepol/cil/test/unit/test_cil_resolve_ast.c new file mode 100644 index 00000000..1540c2b8 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_resolve_ast.c @@ -0,0 +1,11319 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "CilTest.h" + +#include "../../src/cil_build_ast.h" +#include "../../src/cil_resolve_ast.h" +#include "../../src/cil_verify.h" +#include "../../src/cil_internal.h" + +/* this all needs to be moved to a private header file */ +int __cil_resolve_ast_node_helper(struct cil_tree_node *, uint32_t *, void *); +int __cil_disable_children_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *); + +struct cil_args_resolve { + struct cil_db *db; + enum cil_pass pass; + uint32_t *changed; + struct cil_tree_node *callstack; + struct cil_tree_node *optstack; + struct cil_tree_node *macro; +}; + +struct cil_args_resolve *gen_resolve_args(struct cil_db *db, enum cil_pass pass, uint32_t *changed, struct cil_tree_node *calls, struct cil_tree_node *opts, struct cil_tree_node *macro) +{ + struct cil_args_resolve *args = cil_malloc(sizeof(*args)); + args->db = db; + args->pass = pass; + args->changed = changed; + args->callstack = calls; + args->optstack = opts; + args->macro = macro; + + return args; +} + +void test_cil_resolve_name(CuTest *tc) { + char *line[] = { "(", "block", "foo", + "(", "typealias", "test", "type_t", ")", + "(", "type", "test", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_curr = test_db->ast->root->cl_head->cl_head; + struct cil_typealias *test_alias = (struct cil_typealias*)test_curr->data; + struct cil_tree_node *type_node = NULL; + + int rc = cil_resolve_name(test_curr, test_alias->type_str, CIL_SYM_TYPES, args, &type_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_name_invalid_type_neg(CuTest *tc) { + char *line[] = { "(", "block", "foo", + "(", "typealias", "foo.test2", "type_t", ")", + "(", "type", "test", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_curr = test_db->ast->root->cl_head->cl_head; + struct cil_typealias *test_alias = (struct cil_typealias*)test_curr->data; + struct cil_tree_node *type_node = NULL; + + int rc = cil_resolve_name(test_curr, test_alias->type_str, CIL_SYM_TYPES, args, &type_node); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_curr_null_neg(CuTest *tc) { + struct cil_db *test_db; + cil_db_init(&test_db); + + test_db->ast->root = NULL; + + int rc = cil_resolve_ast(test_db, test_db->ast->root); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + + +/* + cil_resolve test cases +*/ + +void test_cil_resolve_roleallow(CuTest *tc) { + char *line[] = {"(", "role", "foo", ")", \ + "(", "role", "bar", ")", \ + "(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roleallow(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_roleallow_srcdecl_neg(CuTest *tc) { + char *line[] = {"(", "role", "bar", ")", \ + "(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + int rc1=cil_build_ast(test_db, test_tree->root, test_db->ast->root); + rc1 = rc1; + + int rc = cil_resolve_roleallow(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_roleallow_tgtdecl_neg(CuTest *tc) { + char *line[] = {"(", "role", "foo", ")", \ + "(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roleallow(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_classmapping_anon(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "open", ")", ")", + "(", "classmap", "files", "(", "read", ")", ")", + "(", "classmapping", "files", "read", "(", "file", "(", "open", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classmapping(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_classmapping_anon_inmacro(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "file", "(", "open", ")", ")", + "(", "macro", "mm", "(", "(", "classpermissionset", "a", ")", ")", + "(", "classmapping", "files", "read", "a", ")", ")", + "(", "call", "mm", "(", "(", "file", "(", "open", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + args->pass = CIL_PASS_CALL1; + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next; + + int rc = cil_resolve_classmapping(test_db->ast->root->cl_head->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_classmapping_anon_inmacro_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "file", "(", "open", ")", ")", + "(", "macro", "mm", "(", "(", "classpermissionset", "a", ")", ")", + "(", "classmapping", "files", "read", "a", ")", ")", + "(", "call", "mm", "(", "(", "DNE", "(", "open", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + args->pass = CIL_PASS_CALL1; + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next; + + int rc = cil_resolve_classmapping(test_db->ast->root->cl_head->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_classmapping_named(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "classpermissionset", "char_w", "(", "char", "(", "read", ")", ")", ")", + "(", "classmapping", "files", "read", "char_w", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classmapping(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_classmapping_named_classmapname_neg(CuTest *tc) { + char *line[] = {"(", "classpermissionset", "char_w", "(", "char", "(", "read", ")", ")", ")", + "(", "classmap", "files", "(", "read", ")", ")", + "(", "classmapping", "files", "read", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classmapping(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_classmapping_anon_classmapname_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "open", ")", ")", + "(", "classmap", "files", "(", "read", ")", ")", + "(", "classmapping", "dne", "read", "(", "file", "(", "open", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classmapping(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_classmapping_anon_permset_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "open", ")", ")", + "(", "classmap", "files", "(", "read", ")", ")", + "(", "classmapping", "files", "read", "(", "dne", "(", "open", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classmapping(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rolebounds(CuTest *tc) { + char *line[] = {"(", "role", "role1", ")", + "(", "role", "role2", ")", + "(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rolebounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_rolebounds_exists_neg(CuTest *tc) { + char *line[] = {"(", "role", "role1", ")", + "(", "role", "role2", ")", + "(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_rolebounds(test_db->ast->root->cl_head->next->next, args); + int rc = cil_resolve_rolebounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_rolebounds_role1_neg(CuTest *tc) { + char *line[] = {"(", "role", "role1", ")", + "(", "role", "role2", ")", + "(", "rolebounds", "role_DNE", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rolebounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rolebounds_role2_neg(CuTest *tc) { + char *line[] = {"(", "role", "role1", ")", + "(", "role", "role2", ")", + "(", "rolebounds", "role1", "role_DNE", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rolebounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_sensalias(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_sensalias(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_sensalias_sensdecl_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_sensalias(test_db->ast->root->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_catalias(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_catalias(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_catalias_catdecl_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_catalias(test_db->ast->root->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_catorder(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c3", ")", + "(", "categoryorder", "(", "c0", "c3", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + int rc2 = cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); +} + +void test_cil_resolve_catorder_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c3", ")", + "(", "categoryorder", "(", "c5", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_dominance(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_dominance(test_db->ast->root->cl_head->next->next->next, args); + int rc2 = cil_resolve_dominance(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); +} + +void test_cil_resolve_dominance_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s6", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_dominance(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_cat_list(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_list *test_cat_list; + cil_list_init(&test_cat_list); + + struct cil_catset *test_catset = (struct cil_catset*)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_cat_list(test_db->ast->root->cl_head->next->next->next, test_catset->cat_list_str, test_cat_list, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_cat_list_catlistnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_list *test_cat_list; + cil_list_init(&test_cat_list); + + struct cil_catset *test_catset = (struct cil_catset*)test_db->ast->root->cl_head->next->next->next->data; + test_catset->cat_list_str = NULL; + + int rc = cil_resolve_cat_list(test_db->ast->root->cl_head->next->next->next, test_catset->cat_list_str, test_cat_list, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_cat_list_rescatlistnull_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_list *test_cat_list = NULL; + + struct cil_catset *test_catset = (struct cil_catset*)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_cat_list(test_db->ast->root->cl_head->next->next->next, test_catset->cat_list_str, test_cat_list, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_cat_list_catrange(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryorder", "(", "c0", "c1", "c2", ")", ")", + "(", "categoryset", "somecats", "(", "c0", "(", "c1", "c2", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + struct cil_list *test_cat_list; + cil_list_init(&test_cat_list); + + struct cil_catset *test_catset = (struct cil_catset*)test_db->ast->root->cl_head->next->next->next->next->data; + + int rc = cil_resolve_cat_list(test_db->ast->root->cl_head->next->next->next->next, test_catset->cat_list_str, test_cat_list, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_cat_list_catrange_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryorder", "(", "c0", "c1", "c2", ")", ")", + "(", "categoryset", "somecats", "(", "c0", "(", "c2", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_list *test_cat_list; + cil_list_init(&test_cat_list); + + cil_resolve_catorder(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MLS; + + struct cil_catset *test_catset = (struct cil_catset*)test_db->ast->root->cl_head->next->next->next->next->data; + + int rc = cil_resolve_cat_list(test_db->ast->root->cl_head->next->next->next->next, test_catset->cat_list_str, test_cat_list, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_cat_list_catname_neg(CuTest *tc) { + char *line[] = {"(", "category", "c5", ")", + "(", "category", "c6", ")", + "(", "category", "c7", ")", + "(", "categoryorder", "(", "c0", "c1", "c2", ")", ")", + "(", "categoryset", "somecats", "(", "c0", "(", "c1", "c2", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_catorder(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MLS; + struct cil_list *test_cat_list; + cil_list_init(&test_cat_list); + + struct cil_catset *test_catset = (struct cil_catset*)test_db->ast->root->cl_head->next->next->next->next->data; + + int rc = cil_resolve_cat_list(test_db->ast->root->cl_head->next->next->next->next, test_catset->cat_list_str, test_cat_list, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_catset(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_catset *test_catset = (struct cil_catset *)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_catset(test_db->ast->root->cl_head->next->next->next, test_catset, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_catset_catlist_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", "c4", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_catset *test_catset = (struct cil_catset *)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_catset(test_db->ast->root->cl_head->next->next->next, test_catset, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_catrange(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "categoryrange", "range", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + args->pass = CIL_PASS_MLS; + + int rc = cil_resolve_catrange(test_db->ast->root->cl_head->next->next->next, (struct cil_catrange*)test_db->ast->root->cl_head->next->next->next->data, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_catrange_catloworder_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "categoryrange", "range", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + test_db->catorder->head = test_db->catorder->head->next; + test_db->catorder->head->next = NULL; + + args->pass = CIL_PASS_MLS; + + int rc = cil_resolve_catrange(test_db->ast->root->cl_head->next->next->next, (struct cil_catrange*)test_db->ast->root->cl_head->next->next->next->data, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_catrange_cathighorder_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "categoryrange", "range", "(", "c255", "c0", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + args->pass = CIL_PASS_MLS; + + int rc = cil_resolve_catrange(test_db->ast->root->cl_head->next->next->next, (struct cil_catrange*)test_db->ast->root->cl_head->next->next->next->data, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_catrange_cat1_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "categoryrange", "range", "(", "c12", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + args->pass = CIL_PASS_MLS; + + int rc = cil_resolve_catrange(test_db->ast->root->cl_head->next->next->next, (struct cil_catrange*)test_db->ast->root->cl_head->next->next->next->data, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_catrange_cat2_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "categoryrange", "range", "(", "c0", "c23", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + args->pass = CIL_PASS_MLS; + + int rc = cil_resolve_catrange(test_db->ast->root->cl_head->next->next->next, (struct cil_catrange*)test_db->ast->root->cl_head->next->next->next->data, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_senscat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_senscat_catrange_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "category", "c500", ")", + "(", "categoryorder", "(", "c0", "c255", "c500", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "(", "c255", "c5", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_catorder(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MLS; + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_senscat_catsetname(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "category", "c500", ")", + "(", "categoryset", "foo", "(", "c0", "c255", "c500", ")", ")", + "(", "categoryorder", "(", "c0", "c255", "c500", ")", ")", + "(", "sensitivitycategory", "s1", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_catset *test_catset = (struct cil_catset *)test_db->ast->root->cl_head->next->next->next->next->next->data; + cil_resolve_catset(test_db->ast->root->cl_head->next->next->next->next->next, test_catset, args); + + args->pass = CIL_PASS_MISC2; + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_senscat_catsetname_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "category", "c500", ")", + "(", "sensitivitycategory", "s1", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_senscat_sublist(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c1", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "(", "c1", "c255", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_senscat_missingsens_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_senscat_category_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c5", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_senscat_currrangecat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c1", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "(", "c1", "c255", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + __cil_verify_order(test_db->dominance, test_db->ast->root, CIL_SENS); + + args->pass = CIL_PASS_MISC2; + + int rc = cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_level(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + int rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + int rc2 = cil_resolve_level(level->next, (struct cil_level*)level->next->data, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); +} + +void test_cil_resolve_level_catlist(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "categoryorder", "(", "c0", "c1", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", "c1", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "(", "c0", "c1", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", "c1", ")", ")", ")", + "(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next; + int rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_level_catset(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "cats", "(", "c0", "c1", "c2", ")", ")", + "(", "categoryorder", "(", "c0", "c1", "c2", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "cats", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "cats", ")", ")", + "(", "level", "high", "(", "s0", "(", "cats", ")", ")", ")", + "(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + struct cil_catset *cs = (struct cil_catset *)test_db->ast->root->cl_head->next->next->next->data; + + cil_resolve_catorder(test_db->ast->root->cl_head->next->next->next->next, args); + + args->pass = CIL_PASS_MLS; + + cil_resolve_catset(test_db->ast->root->cl_head->next->next->next, cs, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next; + int rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_level_catset_name_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "cats", "(", "c0", "c1", "c2", ")", ")", + "(", "categoryorder", "(", "c0", "c1", "c2", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "cats", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "dne", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next; + int rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_level_sens_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s1", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s1", "(", "c0", ")", ")", ")", + "(", "sid", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + int rc2 = cil_resolve_level(level->next, (struct cil_level*)level->next->data, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc2); +} + +void test_cil_resolve_level_cat_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "(", "c1", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c1", ")", ")", ")", + "(", "sid", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + + args->pass = CIL_PASS_MISC3; + int rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + int rc2 = cil_resolve_level(level->next, (struct cil_level*)level->next->data, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc2); +} + +void test_cil_resolve_level_senscat_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s1", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "sid", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + + args->pass = CIL_PASS_MISC3; + int rc = cil_resolve_level(level, (struct cil_level*)level->data, args); + int rc2 = cil_resolve_level(level->next, (struct cil_level*)level->next->data, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, SEPOL_ERR, rc2); +} + +void test_cil_resolve_levelrange_namedlvl(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "levelrange", "range", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_levelrange *lvlrange = (struct cil_levelrange *)test_db->ast->root->cl_head->next->next->next->next->next->data; + + int rc = cil_resolve_levelrange(test_db->ast->root->cl_head->next->next->next->next->next, lvlrange, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_levelrange_namedlvl_low_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "levelrange", "range", "(", "DNE", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_levelrange *lvlrange = (struct cil_levelrange *)test_db->ast->root->cl_head->next->next->next->next->next->data; + + int rc = cil_resolve_levelrange(test_db->ast->root->cl_head->next->next->next->next->next, lvlrange, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_levelrange_namedlvl_high_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "levelrange", "range", "(", "low", "DNE", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_levelrange *lvlrange = (struct cil_levelrange *)test_db->ast->root->cl_head->next->next->next->next->next->data; + + int rc = cil_resolve_levelrange(test_db->ast->root->cl_head->next->next->next->next->next, lvlrange, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_levelrange_anonlvl(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_levelrange *lvlrange = (struct cil_levelrange *)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_levelrange(test_db->ast->root->cl_head->next->next->next, lvlrange, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_levelrange_anonlvl_low_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "DNE", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + struct cil_levelrange *lvlrange = (struct cil_levelrange *)test_db->ast->root->cl_head->next->next->next->data; + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_levelrange(test_db->ast->root->cl_head->next->next->next, lvlrange, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_levelrange_anonlvl_high_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "dne", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + struct cil_levelrange *lvlrange = (struct cil_levelrange *)test_db->ast->root->cl_head->next->next->next->data; + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_levelrange(test_db->ast->root->cl_head->next->next->next, lvlrange, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_constrain(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", "relabelto", ")", ")", + "(", "class", "dir", "(", "create", "relabelto", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "l2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "level", "h2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_constrain(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_constrain_class_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", "relabelto", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "l2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "level", "h2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "mlsconstrain", "(", "foo", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_constrain(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_constrain_perm_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", ")", ")", + "(", "class", "dir", "(", "create", "relabelto", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "l2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "level", "h2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_constrain(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_constrain_perm_resolve_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "l2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "level", "h2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "mlsconstrain", "(", "file", "(", "foo", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_constrain(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_context(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->data; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, test_context, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_context_macro(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "macro", "mm", "(", "(", "levelrange", "range", ")", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "range", ")", ")", ")", + "(", "call", "mm", "(", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->cl_head->data; + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->cl_head, test_context, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_context_macro_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "macro", "mm", "(", "(", "levelrange", "range", ")", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "range", ")", ")", ")", + "(", "call", "mm", "(", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "DNE", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->cl_head->data; + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->cl_head, test_context, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_context_namedrange(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "levelrange", "range", "(", "low", "high", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "range", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->data; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, test_context, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_context_namedrange_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "levelrange", "range", "(", "low", "high", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "DNE", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->data; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, test_context, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_context_user_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->data; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next, test_context, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_context_role_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->data; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next, test_context, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_context_type_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->data; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next, test_context, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_context_anon_level_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "(", "DNE", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_context *test_context = (struct cil_context*)test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->data; + + int rc = cil_resolve_context(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, test_context, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_roletransition(CuTest *tc) { + char *line[] = {"(", "role", "foo_r", ")", + "(", "type", "bar_t", ")", + "(", "role", "foobar_r", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roletransition(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_roletransition_srcdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "bar_t", ")", + "(", "role", "foobar_r", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roletransition(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_roletransition_tgtdecl_neg(CuTest *tc) { + char *line[] = {"(", "role", "foo_r", ")", + "(", "role", "foobar_r", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roletransition(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_roletransition_resultdecl_neg(CuTest *tc) { + char *line[] = {"(", "role", "foo_r", ")", + "(", "type", "bar_t", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roletransition(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_typeattributeset_type_in_multiple_attrs(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "typeattribute", "attrs2", ")", + "(", "type", "type_t", ")", + "(", "typeattributeset", "attrs2", "type_t", ")", + "(", "typeattributeset", "attrs", "type_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next->next->next->next, args); + int rc2 = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); +} + +void test_cil_resolve_typeattributeset_multiple_excludes_with_not(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "typeattribute", "attrs2", ")", + "(", "type", "type_t", ")", + "(", "type", "type_b", ")", + "(", "type", "type_a", ")", + "(", "typeattributeset", "attrs", "(", "and", "type_a", "type_b", ")", ")", + "(", "typeattributeset", "attrs2", "(", "not", "attrs", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_typeattributeset_multiple_types_with_and(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "type", "type_t", ")", + "(", "type", "type_tt", ")", + "(", "typeattributeset", "attrs", "(", "and", "type_t", "type_tt", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_typeattributeset_using_attr(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "typeattribute", "attr_a", ")", + "(", "typeattributeset", "attrs", "attr_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_typeattributeset_name_neg(CuTest *tc) { + char *line[] = {"(", "type", "type_t", ")", + "(", "typeattributeset", "attrs", "type_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_typeattributeset_undef_type_neg(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "typeattributeset", "attrs", "type_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_typeattributeset_not(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "type", "type_t", ")", + "(", "type", "t_t", ")", + "(", "typeattributeset", "attrs", "(", "not", "t_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_typeattributeset_undef_type_not_neg(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "type", "type_t", ")", + "(", "typeattributeset", "attrs", "(", "not", "t_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_typeattributeset(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_typealias(CuTest *tc) { + char *line[] = {"(", "block", "foo", + "(", "typealias", ".foo.test", "type_t", ")", + "(", "type", "test", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typealias(test_db->ast->root->cl_head->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_typealias_neg(CuTest *tc) { + char *line[] = {"(", "block", "foo", + "(", "typealias", ".foo", "apache_alias", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typealias(test_db->ast->root->cl_head->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_typebounds(CuTest *tc) { + char *line[] = {"(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typebounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_typebounds_repeatbind_neg(CuTest *tc) { + char *line[] = {"(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "typebounds", "type_a", "type_b", ")", + "(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typebounds(test_db->ast->root->cl_head->next->next, args); + int rc2 = cil_resolve_typebounds(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_ERR, rc2); +} + +void test_cil_resolve_typebounds_type1_neg(CuTest *tc) { + char *line[] = {"(", "type", "type_b", ")", + "(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typebounds(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_typebounds_type2_neg(CuTest *tc) { + char *line[] = {"(", "type", "type_a", ")", + "(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typebounds(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_typepermissive(CuTest *tc) { + char *line[] = {"(", "type", "type_a", ")", + "(", "typepermissive", "type_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typepermissive(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_typepermissive_neg(CuTest *tc) { + char *line[] = {"(", "type", "type_a", ")", + "(", "typepermissive", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_typepermissive(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nametypetransition(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "type", "foobar", ")", + "(", "nametypetransition", "str", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nametypetransition(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nametypetransition_src_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "type", "foobar", ")", + "(", "nametypetransition", "str", "wrong", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nametypetransition(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nametypetransition_tgt_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "type", "foobar", ")", + "(", "nametypetransition", "str", "foo", "wrong", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nametypetransition(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nametypetransition_class_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "type", "foobar", ")", + "(", "nametypetransition", "str", "foo", "bar", "wrong", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nametypetransition(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nametypetransition_dest_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "type", "foobar", ")", + "(", "nametypetransition", "str", "foo", "bar", "file", "wrong", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nametypetransition(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_rangetransition_namedrange_anon(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "levelrange", "l", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "l", ")", ")", + "(", "call", "mm", "(", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_rangetransition_namedrange_anon_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "levelrange", "l", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "l", ")", ")", + "(", "call", "mm", "(", "(", "DNE", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_rangetransition_namedrange(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "levelrange", "foo_range", "(", "low", "high", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "foo_range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_rangetransition_namedrange_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "levelrange", "foo_range", "(", "low", "high", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "DNE", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition_type1_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_DNE", "type_b", "class_", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition_type2_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_DNE", "class_", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition_class_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_DNE", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition_call_level_l_anon(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "l", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "l", "high", ")", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_rangetransition_call_level_l_anon_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "l", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "l", "high", ")", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c4", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_rangetransition_call_level_h_anon(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "h", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low", "h", ")", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_rangetransition_call_level_h_anon_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "h", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low", "h", ")", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c4", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next->next; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_rangetransition_level_l_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low_DNE", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition_level_h_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low", "high_DNE", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition_anon_level_l(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "(", "s0", "(", "c0", ")", ")", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_rangetransition_anon_level_l_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "(", "s0", "(", "c_DNE", ")", ")", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_rangetransition_anon_level_h(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_rangetransition_anon_level_h_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low", "(", "s_DNE", "(", "c0", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_rangetransition(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_classcommon(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", ")", ")", + "(", "common", "file", "(", "write", ")", ")", + "(", "classcommon", "file", "file", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classcommon(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_classcommon_no_class_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", + "(", "classcommon", "foo", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classcommon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_classcommon_no_common_neg(CuTest *tc) { + char *line[] = {"(", "common", "foo", "(", "read", ")", ")", + "(", "classcommon", "foo", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_classcommon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_classpermset_named(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "char", "(", "read", ")", ")", + "(", "classpermissionset", "char_w", "(", "char", "(", "read", ")", ")", ")", + "(", "classmapping", "files", "read", "char_w", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_classpermset *cps = test_db->ast->root->cl_head->next->next->data; + + int rc = cil_resolve_classpermset(test_db->ast->root->cl_head->next->next->next, cps, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_classpermset_named_namedpermlist(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "char", "(", "read", ")", ")", + "(", "classpermissionset", "char_w", "(", "char", "baz", ")", ")", + "(", "permissionset", "baz", "(", "read", ")", ")", + "(", "classmapping", "files", "read", "char_w", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_classpermset *cps = test_db->ast->root->cl_head->next->next->data; + + int rc = cil_resolve_classpermset(test_db->ast->root->cl_head->next->next->next, cps, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_classpermset_named_permlist_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "char", "(", "read", ")", ")", + "(", "classpermissionset", "char_w", "(", "dne", "(", "read", ")", ")", ")", + "(", "classmapping", "files", "read", "char_w", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_classpermset *cps = test_db->ast->root->cl_head->next->next->data; + + int rc = cil_resolve_classpermset(test_db->ast->root->cl_head->next->next->next, cps, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_classpermset_named_unnamedcps_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "char", "(", "read", ")", ")", + "(", "classpermissionset", "char_w", "(", "char", "(", "read", ")", ")", ")", + "(", "classmapping", "files", "read", "char_w", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_classpermset *cps; + cil_classpermset_init(&cps); + + int rc = cil_resolve_classpermset(test_db->ast->root->cl_head->next->next->next, cps, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_classpermset_anon(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "classmapping", "files", "read", "(", "char", "(", "read", ")", ")", ")", + "(", "class", "char", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_classpermset *cps = ((struct cil_classmapping*)test_db->ast->root->cl_head->next->data)->classpermsets_str->head->data; + + int rc = cil_resolve_classpermset(test_db->ast->root->cl_head->next, cps, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_classpermset_anon_namedpermlist(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "classmapping", "files", "read", "(", "char", "baz", ")", ")", + "(", "permissionset", "baz", "(", "read", ")", ")", + "(", "class", "char", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_classpermset *cps = ((struct cil_classmapping*)test_db->ast->root->cl_head->next->data)->classpermsets_str->head->data; + + int rc = cil_resolve_classpermset(test_db->ast->root->cl_head->next, cps, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_classpermset_anon_permlist_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "classmapping", "files", "read", "(", "char", "(", "dne", ")", ")", ")", + "(", "class", "char", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_classpermset *cps = ((struct cil_classmapping*)test_db->ast->root->cl_head->next->data)->classpermsets_str->head->data; + + int rc = cil_resolve_classpermset(test_db->ast->root->cl_head->next, cps, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_avrule(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_avrule_permset(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "permissionset", "baz", "(", "open", "write", ")", ")", + "(", "allow", "test", "foo", "(", "bar", "baz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_avrule_permset_neg(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "permissionset", "baz", "(", "open", "close", ")", ")", + "(", "allow", "test", "foo", "(", "bar", "dne", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_avrule_permset_permdne_neg(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "permissionset", "baz", "(", "open", "dne", ")", ")", + "(", "allow", "test", "foo", "(", "bar", "baz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_avrule_firsttype_neg(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "allow", "fail1", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_avrule_secondtype_neg(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "allow", "test", "fail2", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_avrule_class_neg(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "allow", "test", "foo", "(", "fail3", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_avrule_perm_neg(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "allow", "test", "foo", "(", "bar", "(", "execute", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_avrule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_transition(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_type_rule_transition_srcdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_transition_tgtdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_transition_objdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "type", "foobar", ")", + "(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_transition_resultdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_change(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_type_rule_change_srcdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_change_tgtdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_change_objdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "type", "foobar", ")", + "(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_change_resultdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_member(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_type_rule_member_srcdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_member_tgtdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_member_objdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "type", "foobar", ")", + "(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_type_rule_member_resultdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_type_rule(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_filecon(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "filecon", "root", "path", "file", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_filecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_filecon_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "filecon", "root", "path", "file", "conn", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_filecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_filecon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "filecon", "root", "path", "file", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_filecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_filecon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "filecon", "root", "path", "file", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_filecon(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_portcon(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "portcon", "udp", "25", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_portcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_portcon_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "portcon", "udp", "25", "conn", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_portcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_portcon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "portcon", "udp", "25", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_portcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_portcon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "portcon", "udp", "25", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_portcon(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_genfscon(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "genfscon", "type", "path", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_genfscon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_genfscon_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "genfscon", "type", "path", "conn", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_genfscon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_genfscon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "genfscon", "type", "path", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_genfscon(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_genfscon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "genfscon", "type", "path", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_genfscon(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nodecon_ipv4(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "ipaddr", "netmask", "192.168.1.1", ")", + "(", "nodecon", "ip", "netmask", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nodecon_ipv6(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "2001:0DB8:AC10:FE01::", ")", + "(", "ipaddr", "netmask", "2001:0DB8:AC10:FE01::", ")", + "(", "nodecon", "ip", "netmask", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nodecon_anonipaddr_ipv4(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "netmask", "192.168.1.1", ")", + "(", "nodecon", "(", "192.168.1.1", ")", "netmask", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nodecon_anonnetmask_ipv4(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "nodecon", "ip", "(", "192.168.1.1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nodecon_anonipaddr_ipv6(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "netmask", "2001:0DB8:AC10:FE01::", ")", + "(", "nodecon", "(", "2001:0DB8:AC10:FE01::", ")", "netmask", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nodecon_anonnetmask_ipv6(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "2001:0DB8:AC10:FE01::", ")", + "(", "nodecon", "ip", "(", "2001:0DB8:AC10:FE01::", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nodecon_diffipfam_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "2001:0DB8:AC10:FE01::", ")", + "(", "nodecon", "ip", "(", "192.168.1.1", ")", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_nodecon_context_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "ipaddr", "netmask", "192.168.1.1", ")", + "(", "nodecon", "n", "netmask", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nodecon_ipaddr_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "ipaddr", "netmask", "192.168.1.1", ")", + "(", "nodecon", "ip", "n", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nodecon_netmask_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "nodecon", "ip", "ip", "conn", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_nodecon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "nodecon", "ip", "ip", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_nodecon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "nodecon", "ip", "ip", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_nodecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_netifcon(CuTest *tc) { + char *line[] = {"(", "context", "if_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_netifcon(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_netifcon_otf_neg(CuTest *tc) { + char *line[] = {"(", "context", "if_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_netifcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_netifcon_interface_neg(CuTest *tc) { + char *line[] = {"(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_netifcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_netifcon_unnamed(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_netifcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_netifcon_unnamed_packet_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_netifcon(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_netifcon_unnamed_otf_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", + "(", "system_u", "foo_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_netifcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_netifcon_sublist_secondlist_missing_neg(CuTest *tc) { + char *line[] = {"(", "netifcon", "eth1", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_netifcon(test_db->ast->root->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_pirqcon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pirqcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_pirqcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_pirqcon_context_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pirqcon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_pirqcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_pirqcon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "etc_t", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "pirqcon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_pirqcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_pirqcon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "pirqcon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_pirqcon(test_db->ast->root->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_iomemcon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "iomemcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_iomemcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_iomemcon_context_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "iomemcon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_iomemcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_iomemcon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "etc_t", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "iomemcon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_iomemcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_iomemcon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "iomemcon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_iomemcon(test_db->ast->root->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ioportcon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "ioportcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_ioportcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ioportcon_context_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "ioportcon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_ioportcon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ioportcon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "etc_t", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "ioportcon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_ioportcon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ioportcon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "ioportcon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_ioportcon(test_db->ast->root->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_pcidevicecon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pcidevicecon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_pcidevicecon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_pcidevicecon_context_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pcidevicecon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_pcidevicecon(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_pcidevicecon_anon_context(CuTest *tc) { + char *line[] = {"(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "etc_t", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "pcidevicecon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_pcidevicecon(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_pcidevicecon_anon_context_neg(CuTest *tc) { + char *line[] = {"(", "pcidevicecon", "1", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_pcidevicecon(test_db->ast->root->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_fsuse(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", + "(", "fsuse", "xattr", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_fsuse(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_fsuse_nocontext_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", + "(", "fsuse", "xattr", "ext3", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_fsuse(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_fsuse_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", + "(", "fsuse", "xattr", "ext3", "conn", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_fsuse(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_fsuse_anon(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "fsuse", "xattr", "ext3", "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_fsuse(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_fsuse_anon_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "fsuse", "xattr", "ext3", "(", "system_uu", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_fsuse(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_sidcontext(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "sid", "test", ")", + "(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_sidcontext(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_sidcontext_named_levels(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "sid", "test", ")", + "(", "sidcontext", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_tree_node *level = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + cil_resolve_level(level, (struct cil_level*)level->data, args); + cil_resolve_level(level->next, (struct cil_level*)level->next->data, args); + int rc = cil_resolve_sidcontext(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_sidcontext_named_context(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "context", "con", "(", "blah_u", "blah_r", "blah_t", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", + "(", "sid", "test", ")", + "(", "sidcontext", "test", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_tree_node *context = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + cil_resolve_context(context, (struct cil_context*)context->data, args); + + int rc = cil_resolve_sidcontext(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_sidcontext_named_context_wrongname_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "context", "con", "(", "blah_u", "blah_r", "blah_t", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", + "(", "sid", "test", ")", + "(", "sidcontext", "test", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + struct cil_tree_node *context = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + cil_resolve_context(context, (struct cil_context*)context->data, args); + + int rc = cil_resolve_sidcontext(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_sidcontext_named_context_invaliduser_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "sid", "test", ")", + "(", "sidcontext", "test", "(", "", "blah_r", "blah_t", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + int rc = cil_resolve_sidcontext(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_blockinherit(CuTest *tc) { + char *line[] = {"(", "block", "baz", "(", "type", "b", ")", ")", + "(", "block", "foo", "(", "type", "a", ")", + "(", "blockinherit", "baz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_blockinherit(test_db->ast->root->cl_head->next->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_blockinherit_blockstrdne_neg(CuTest *tc) { + char *line[] = {"(", "block", "baz", "(", "type", "b", ")", ")", + "(", "block", "foo", "(", "type", "a", ")", + "(", "blockinherit", "dne", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_blockinherit(test_db->ast->root->cl_head->next->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_in_block(CuTest *tc) { + char *line[] = {"(", "class", "char", "(", "read", ")", ")", + "(", "block", "foo", "(", "type", "a", ")", ")", + "(", "in", "foo", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_in(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_in_blockstrdne_neg(CuTest *tc) { + char *line[] = {"(", "class", "char", "(", "read", ")", ")", + "(", "in", "foo", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_in(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_in_macro(CuTest *tc) { + char *line[] = {"(", "class", "char", "(", "read", "write", ")", ")", + "(", "macro", "mm", "(", "(", "class", "a", ")", ")", + "(", "allow", "foo", "bar", "(", "file", "(", "write", ")", ")", ")", ")", + "(", "in", "mm", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_in(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_in_optional(CuTest *tc) { + char *line[] = {"(", "class", "char", "(", "read", "write", ")", ")", + "(", "optional", "opt", "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", + "(", "in", "opt", "(", "allow", "test", "baz", "(", "char", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_in(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_noparam(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", ")", ")", + "(", "type", "b", ")", + "(", "allow", "qaz", "b", "file", "(", "read", ")", ")", ")", + "(", "call", "mm", "(", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_type(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_role(CuTest *tc) { + char *line[] = {"(", "role", "role_r", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "role", "a", ")", ")", + "(", "role", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "role_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_user(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "user", "a", ")", ")", + "(", "user", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "user_u", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_sens(CuTest *tc) { + char *line[] = {"(", "sensitivity", "sens", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "sensitivity", "a", ")", ")", + "(", "sensitivity", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "sens", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_cat(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "category", "a", ")", ")", + "(", "category", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "c0", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_catset(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", + "(", "macro", "mm", "(", "(", "categoryset", "foo", ")", ")", + "(", "level", "bar", "(", "s0", "foo", ")", ")", ")", + "(", "call", "mm", "(", "somecats", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_catset_anon(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "macro", "mm", "(", "(", "categoryset", "foo", ")", ")", + "(", "level", "bar", "(", "s0", "foo", ")", ")", ")", + "(", "call", "mm", "(", "(", "c0", "c1", "c2", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_catset_anon_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "macro", "mm", "(", "(", "categoryset", "foo", ")", ")", + "(", "level", "bar", "(", "s0", "foo", ")", ")", ")", + "(", "call", "mm", "(", "(", "c5", "(", "c2", ")", "c4", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_level(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", "(", "level", "lvl_h", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", ")", + "(", "call", "mm", "(", "l", "h", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_level_anon(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "h", ")", ")", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_level_anon_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "h", ")", ")", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c0", "(", "c5", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_ipaddr(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "lvl_l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "lvl_h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", + "(", "ipaddr", "netmask", "192.168.0.1", ")", + "(", "ipaddr", "ip", "192.168.0.1", ")", + "(", "macro", "mm", "(", "(", "ipaddr", "addr", ")", ")", + "(", "nodecon", "addr", "netmask", "con", ")", ")", + "(", "call", "mm", "(", "ip", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_ipaddr_anon(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "lvl_l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "lvl_h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", + "(", "ipaddr", "netmask", "192.168.0.1", ")", + "(", "macro", "mm", "(", "(", "ipaddr", "addr", ")", ")", + "(", "nodecon", "addr", "netmask", "con", ")", ")", + "(", "call", "mm", "(", "(", "192.168.1.1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_ipaddr_anon_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "lvl_l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "lvl_h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", + "(", "ipaddr", "netmask", "192.168.0.1", ")", + "(", "macro", "mm", "(", "(", "ipaddr", "addr", ")", ")", + "(", "nodecon", "addr", "netmask", "con", ")", ")", + "(", "call", "mm", "(", "(", "192.1.1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_class(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "class", "a", ")", ")", + "(", "class", "b", "(", "read", ")", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_classmap(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "open", ")", ")", + "(", "macro", "mm", "(", "(", "classmap", "a", ")", ")", + "(", "classmapping", "a", "read", "(", "file", "(", "open", ")", ")", ")", ")", + "(", "call", "mm", "(", "(", "read", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_permset(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "open", ")", ")", + "(", "type", "dead", ")", + "(", "type", "bar", ")", + "(", "class", "baz", "(", "close", "read", "open", ")", ")", + "(", "macro", "mm", "(", "(", "permissionset", "a", ")", ")", + "(", "allow", "dead", "bar", "(", "baz", "a", ")", ")", ")", + "(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_permset_anon(CuTest *tc) { + char *line[] = {"(", "type", "dead", ")", + "(", "type", "bar", ")", + "(", "class", "baz", "(", "close", "read", "open", ")", ")", + "(", "macro", "mm", "(", "(", "permissionset", "a", ")", ")", + "(", "allow", "dead", "bar", "(", "baz", "a", ")", ")", ")", + "(", "call", "mm", "(", "(", "read", "open", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_classpermset_named(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "file", "(", "open", ")", ")", + "(", "classpermissionset", "char_w", "(", "file", "(", "open", ")", ")", ")", + "(", "macro", "mm", "(", "(", "classpermissionset", "a", ")", ")", + "(", "classmapping", "files", "read", "a", ")", ")", + "(", "call", "mm", "(", "char_w", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_classpermset_anon(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "file", "(", "open", ")", ")", + "(", "macro", "mm", "(", "(", "classpermissionset", "a", ")", ")", + "(", "classmapping", "files", "read", "a", ")", ")", + "(", "call", "mm", "(", "(", "file", "(", "open", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_classpermset_anon_neg(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "file", "(", "open", ")", ")", + "(", "macro", "mm", "(", "(", "classpermissionset", "a", ")", ")", + "(", "classmapping", "files", "read", "a", ")", ")", + "(", "call", "mm", "(", "(", "file", "(", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_unknown_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "class", "a", ")", ")", + "(", "class", "b", "(", "read", ")", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *macro_node = NULL; + cil_resolve_name(test_db->ast->root->cl_head->next->next->next, ((struct cil_call*)test_db->ast->root->cl_head->next->next->next->data)->macro_str, CIL_SYM_BLOCKS, args, ¯o_node); + ((struct cil_call*)test_db->ast->root->cl_head->next->next->next->data)->macro = (struct cil_macro*)macro_node->data; + free(((struct cil_call*)test_db->ast->root->cl_head->next->next->next->data)->macro_str); + ((struct cil_call*)test_db->ast->root->cl_head->next->next->next->data)->macro_str = NULL; + + ((struct cil_call*)test_db->ast->root->cl_head->next->next->next->data)->macro->params->head->flavor = CIL_NETIFCON; + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_unknowncall_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "class", "a", ")", ")", + "(", "class", "b", "(", "read", ")", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "m", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_call1_extraargs_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "class", "a", ")", ")", + "(", "class", "b", "(", "read", ")", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "foo", "bar", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_copy_dup(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "qaz", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call1_missing_arg_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", "(", "level", "lvl_h", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", ")", + "(", "call", "mm", "(", "l", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_paramsflavor_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *macro_node = NULL; + + struct cil_call *new_call = ((struct cil_call*)test_db->ast->root->cl_head->next->next->next->data); + cil_resolve_name(test_db->ast->root->cl_head->next->next->next, new_call->macro_str, CIL_SYM_BLOCKS, args, ¯o_node); + new_call->macro = (struct cil_macro*)macro_node->data; + struct cil_list_item *item = new_call->macro->params->head; + item->flavor = CIL_CONTEXT; + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call1_unknownflavor_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *macro_node = NULL; + + struct cil_call *new_call = ((struct cil_call*)test_db->ast->root->cl_head->next->next->next->data); + cil_resolve_name(test_db->ast->root->cl_head->next->next->next, new_call->macro_str, CIL_SYM_BLOCKS, args, ¯o_node); + new_call->macro = (struct cil_macro*)macro_node->data; + struct cil_list_item *item = new_call->macro->params->head; + ((struct cil_param*)item->data)->flavor = CIL_CONTEXT; + + int rc = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call2_type(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_role(CuTest *tc) { + char *line[] = {"(", "role", "role_r", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "role", "a", ")", ")", + "(", "role", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "role_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_user(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "user", "a", ")", ")", + "(", "user", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "user_u", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_sens(CuTest *tc) { + char *line[] = {"(", "sensitivity", "sens", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "sensitivity", "a", ")", ")", + "(", "sensitivity", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "sens", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_cat(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "category", "a", ")", ")", + "(", "category", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "c0", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_catset(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", + "(", "macro", "mm", "(", "(", "categoryset", "foo", ")", ")", + "(", "level", "bar", "(", "s0", "foo", ")", ")", ")", + "(", "call", "mm", "(", "somecats", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_catset_anon(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "macro", "mm", "(", "(", "categoryset", "foo", ")", ")", + "(", "level", "bar", "(", "s0", "foo", ")", ")", ")", + "(", "call", "mm", "(", "(", "c0", "c1", "c2", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_permset(CuTest *tc) { + char *line[] = {"(", "permissionset", "foo", "(", "read", "open", ")", ")", + "(", "class", "dead", "(", "close", ")", ")", + "(", "class", "bar", "(", "close", ")", ")", + "(", "class", "baz", "(", "close", ")", ")", + "(", "macro", "mm", "(", "(", "permissionset", "a", ")", ")", + "(", "allow", "dead", "bar", "(", "baz", "a", ")", ")", ")", + "(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_permset_anon(CuTest *tc) { + char *line[] = {"(", "class", "dead", "(", "close", ")", ")", + "(", "class", "bar", "(", "close", ")", ")", + "(", "class", "baz", "(", "close", ")", ")", + "(", "macro", "mm", "(", "(", "permissionset", "a", ")", ")", + "(", "allow", "dead", "bar", "(", "baz", "a", ")", ")", ")", + "(", "call", "mm", "(", "(", "read", "open", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_classpermset_named(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "file", "(", "open", ")", ")", + "(", "classpermissionset", "char_w", "(", "file", "(", "open", ")", ")", ")", + "(", "macro", "mm", "(", "(", "classpermissionset", "a", ")", ")", + "(", "classmapping", "files", "read", "a", ")", ")", + "(", "call", "mm", "(", "char_w", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_classpermset_anon(CuTest *tc) { + char *line[] = {"(", "classmap", "files", "(", "read", ")", ")", + "(", "class", "file", "(", "open", ")", ")", + "(", "macro", "mm", "(", "(", "classpermissionset", "a", ")", ")", + "(", "classmapping", "files", "read", "a", ")", ")", + "(", "call", "mm", "(", "(", "file", "(", "open", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_class(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "class", "a", ")", ")", + "(", "class", "b", "(", "read", ")", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_classmap(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "open", ")", ")", + "(", "classmap", "files", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "classmap", "a", ")", ")", + "(", "classmapping", "a", "read", "(", "file", "(", "open", ")", ")", ")", ")", + "(", "call", "mm", "(", "files", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); +} + +void test_cil_resolve_call2_level(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", "(", "level", "lvl_h", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", ")", + "(", "call", "mm", "(", "l", "h", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_level_anon(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "h", ")", ")", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_ipaddr(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "lvl_l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "lvl_h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", + "(", "ipaddr", "netmask", "192.168.0.1", ")", + "(", "ipaddr", "ip", "192.168.0.1", ")", + "(", "macro", "mm", "(", "(", "ipaddr", "addr", ")", ")", + "(", "nodecon", "addr", "netmask", "con", ")", ")", + "(", "call", "mm", "(", "ip", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_ipaddr_anon(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "lvl_l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "lvl_h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", + "(", "ipaddr", "netmask", "192.168.0.1", ")", + "(", "macro", "mm", "(", "(", "ipaddr", "addr", ")", ")", + "(", "nodecon", "addr", "netmask", "con", ")", ")", + "(", "call", "mm", "(", "(", "192.168.1.1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_call2_unknown_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", "(", "level", "lvl_h", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", ")", + "(", "call", "mm", "(", "l", "h", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + ((struct cil_args*)((struct cil_list_item *)((struct cil_call *)test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->data)->args->head)->data)->flavor = CIL_SYM_UNKNOWN; + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_call2_name_neg(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "class", "a", ")", ")", + "(", "class", "b", "(", "read", ")", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_name_call_args(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_resolve_name_call_args((struct cil_call *)test_db->ast->root->cl_head->next->next->next->data, "a", CIL_SYM_TYPES, &test_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_name_call_args_multipleparams(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "user", "system_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "level", "l", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "h", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "level", "lvl_l", ")", "(", "level", "lvl_h", ")", ")", + "(", "context", "foo", "(", "system_u", "role_r", "type_t", "(", "lvl_l", "lvl_h", ")", ")", ")", ")", + "(", "call", "mm", "(", "l", "h", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, args); + int rc = cil_resolve_name_call_args((struct cil_call *)test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->data, "lvl_h", CIL_SYM_LEVELS, &test_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_name_call_args_diffflavor(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_resolve_name_call_args((struct cil_call *)test_db->ast->root->cl_head->next->next->next->data, "qaz", CIL_LEVEL, &test_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_name_call_args_callnull_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_resolve_name_call_args(NULL, "qaz", CIL_LEVEL, &test_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_name_call_args_namenull_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_resolve_name_call_args((struct cil_call *)test_db->ast->root->cl_head->next->next->next->data, NULL, CIL_LEVEL, &test_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_name_call_args_callargsnull_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_resolve_name_call_args((struct cil_call *)test_db->ast->root->cl_head->next->next->next->data, "qas", CIL_LEVEL, &test_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_name_call_args_name_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "baz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node = NULL; + //cil_tree_node_init(&test_node); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + cil_resolve_call2(test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_resolve_name_call_args((struct cil_call *)test_db->ast->root->cl_head->next->next->next->data, "qas", CIL_TYPE, &test_node); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_expr_stack_bools(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", + "(", "boolean", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_booleanif *bif = (struct cil_booleanif*)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_expr_stack(bif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_expr_stack_tunables(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_expr_stack_type(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", "relabelto", ")", ")", + "(", "class", "dir", "(", "create", "relabelto", ")", ")", + "(", "type", "t1", ")", + "(", "type", "type_t", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "t1", "type_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_constrain *cons = (struct cil_constrain*)test_db->ast->root->cl_head->next->next->next->next->data; + + int rc = cil_resolve_expr_stack(cons->expr, test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_expr_stack_role(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", "relabelto", ")", ")", + "(", "class", "dir", "(", "create", "relabelto", ")", ")", + "(", "role", "r1", ")", + "(", "role", "role_r", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "role_r", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_constrain *cons = (struct cil_constrain*)test_db->ast->root->cl_head->next->next->next->next->data; + + int rc = cil_resolve_expr_stack(cons->expr, test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_expr_stack_user(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", "relabelto", ")", ")", + "(", "class", "dir", "(", "create", "relabelto", ")", ")", + "(", "user", "u1", ")", + "(", "user", "user_u", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "u1", "user_u", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_constrain *cons = (struct cil_constrain*)test_db->ast->root->cl_head->next->next->next->next->data; + + int rc = cil_resolve_expr_stack(cons->expr, test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_expr_stack_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", + "(", "boolean", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "booleanif", "(", "and", "beef", "baf", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_booleanif *bif = (struct cil_booleanif*)test_db->ast->root->cl_head->next->next->next->data; + + int rc = cil_resolve_expr_stack(bif->expr_stack,test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_expr_stack_emptystr_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", + "(", "boolean", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_booleanif *bif = (struct cil_booleanif*)test_db->ast->root->cl_head->next->next->next->data; + ((struct cil_conditional*)bif->expr_stack->head->data)->str = NULL; + + int rc = cil_resolve_expr_stack(bif->expr_stack,test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_boolif(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", + "(", "boolean", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_boolif(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_boolif_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", + "(", "boolean", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "booleanif", "(", "and", "dne", "N/A", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_boolif(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_evaluate_expr_stack_and(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_evaluate_expr_stack_not(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "not", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_evaluate_expr_stack_or(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "or", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_evaluate_expr_stack_xor(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "xor", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_evaluate_expr_stack_eq(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "eq", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_evaluate_expr_stack_neq(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "neq", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_evaluate_expr_stack_oper1(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "tunable", "baz", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "(", "or", "foo", "bar", ")", "baz", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "jaz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_evaluate_expr_stack_oper2(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "tunable", "baz", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "baz", "(", "or", "foo", "bar", ")", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "jaz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tunableif *tif = (struct cil_tunableif*)test_db->ast->root->cl_head->next->next->next->next->data; + + cil_resolve_expr_stack(tif->expr_stack, test_db->ast->root->cl_head->next->next->next->next, args); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} +/* +void test_cil_evaluate_expr_stack_neg(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "neq", "foo", "bar", ")", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint16_t result = CIL_FALSE; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + struct cil_conditional *new_cond; + cil_conditional_init(&new_cond); + new_cond->flavor = CIL_COND; + char *baz = "baz"; + new_cond->str = baz; + new_cond->flavor = CIL_TUNABLE; + + struct cil_tunableif *tif = test_db->ast->root->cl_head->next->next->next->next->data; + + test_node->data = new_cond; + test_node->cl_head = tif->expr_stack; + tif->expr_stack->parent = test_node; + + cil_resolve_expr_stack(test_db, tif->expr_stack, test_db->ast->root->cl_head->next->next->next, NULL); + int rc = cil_evaluate_expr_stack(tif->expr_stack, &result); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} +*/ +void test_cil_resolve_tunif_false(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "false", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_tunif(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_tunif_true(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "true", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_tunif(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_tunif_resolveexpr_neg(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "dne", "N/A", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_tunif(test_db->ast->root->cl_head->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} +/* +void test_cil_resolve_tunif_evaluateexpr_neg(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + struct cil_tree_node *test_node; + cil_tree_node_init(&test_node); + + struct cil_conditional *new_cond; + cil_conditional_init(&new_cond); + new_cond->flavor = CIL_COND; + char *baz = "baz"; + new_cond->str = baz; + new_cond->flavor = CIL_TUNABLE; + + struct tunableif *tif = test_db->ast->root->cl_head->next->next->next->data; + + test_node->data = new_cond; + test_node->cl_head = tif->expr_stack; + tif->expr_stack->parent = test_node; + + int rc = cil_resolve_tunif(test_db, test_db->ast->root->cl_head->next->next->next, NULL); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} +*/ +void test_cil_resolve_userbounds(CuTest *tc) { + char *line[] = {"(", "user", "user1", ")", + "(", "user", "user2", ")", + "(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_userbounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_userbounds_exists_neg(CuTest *tc) { + char *line[] = {"(", "user", "user1", ")", + "(", "user", "user2", ")", + "(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_userbounds(test_db->ast->root->cl_head->next->next, args); + int rc = cil_resolve_userbounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_userbounds_user1_neg(CuTest *tc) { + char *line[] = {"(", "user", "user1", ")", + "(", "user", "user2", ")", + "(", "userbounds", "user_DNE", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_userbounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userbounds_user2_neg(CuTest *tc) { + char *line[] = {"(", "user", "user1", ")", + "(", "user", "user2", ")", + "(", "userbounds", "user1", "user_DNE", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_userbounds(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_roletype(CuTest *tc) { + char *line[] = {"(", "role", "admin_r", ")", + "(", "type", "admin_t", ")", + "(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roletype(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_roletype_type_neg(CuTest *tc) { + char *line[] = {"(", "role", "admin_r", ")", + "(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roletype(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_roletype_role_neg(CuTest *tc) { + char *line[] = {"(", "type", "admin_t", ")", + "(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_roletype(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userrole(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + int rc = cil_resolve_userrole(test_db->ast->root->cl_head->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_userrole_user_neg(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_userrole(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userrole_role_neg(CuTest *tc) { + char *line[] = {"(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = cil_resolve_userrole(test_db->ast->root->cl_head->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userlevel(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "userlevel", "foo_u", "low", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userlevel(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_userlevel_macro(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "macro", "mm", "(", "(", "level", "l", ")", ")", + "(", "userlevel", "foo_u", "l", ")", ")", + "(", "call", "mm", "(", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + + args->pass = CIL_PASS_CALL1; + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next; + + int rc = cil_resolve_userlevel(test_db->ast->root->cl_head->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_userlevel_macro_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "macro", "mm", "(", "(", "level", "l", ")", ")", + "(", "userlevel", "foo_u", "l", ")", ")", + "(", "call", "mm", "(", "(", "DNE", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next; + + int rc = cil_resolve_userlevel(test_db->ast->root->cl_head->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_userlevel_level_anon(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "userlevel", "foo_u", "(", "s0", "(", "c0", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userlevel(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_userlevel_level_anon_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "userlevel", "foo_u", "(", "s0", "(", "DNE", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userlevel(test_db->ast->root->cl_head->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userlevel_user_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "userlevel", "DNE", "low", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userlevel(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userlevel_level_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "userlevel", "foo_u", "DNE", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userlevel(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userrange(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", + "(", "userrange", "foo_u", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + int rc = cil_resolve_userrange(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_userrange_macro(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "levelrange", "range", ")", ")", + "(", "userrange", "foo_u", "range", ")", ")", + "(", "call", "mm", "(", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + + int rc = cil_resolve_userrange(test_db->ast->root->cl_head->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_userrange_macro_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "macro", "mm", "(", "(", "levelrange", "range", ")", ")", + "(", "userrange", "foo_u", "range", ")", ")", + "(", "call", "mm", "(", "(", "DNE", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc2 = cil_resolve_call1(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc3 = cil_resolve_call2(test_db->ast->root->cl_head->next->next->next->next->next->next->next, args); + + args->pass = CIL_PASS_MISC2; + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + args->callstack = test_db->ast->root->cl_head->next->next->next->next->next->next->next; + + int rc = cil_resolve_userrange(test_db->ast->root->cl_head->next->next->next->next->next->next->next->cl_head, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, SEPOL_OK, rc2); + CuAssertIntEquals(tc, SEPOL_OK, rc3); +} + +void test_cil_resolve_userrange_range_anon(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "userrange", "foo_u", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userrange(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_userrange_range_anon_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "userrange", "foo_u", "(", "DNE", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userrange(test_db->ast->root->cl_head->next->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userrange_user_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", + "(", "userrange", "DNE", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userrange(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_userrange_range_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", + "(", "userrange", "foo_u", "DNE", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_senscat(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_MISC3; + + int rc = cil_resolve_userrange(test_db->ast->root->cl_head->next->next->next->next->next, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_disable_children_helper_optional_enabled(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "baz", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_optional_disabled(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "baz", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + ((struct cil_optional *)test_db->ast->root->cl_head->data)->datum.state = CIL_STATE_DISABLED; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_block(CuTest *tc) { + char *line[] = {"(", "block", "a", "(", "type", "log", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_user(CuTest *tc) { + char *line[] = {"(", "user", "staff_u", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_role(CuTest *tc) { + char *line[] = {"(", "role", "role_r", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_type(CuTest *tc) { + char *line[] = {"(", "type", "type_t", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_typealias(CuTest *tc) { + char *line[] = {"(", "typealias", ".test.type", "type_t", ")", "(", "type", "test", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_common(CuTest *tc) { + char *line[] = {"(", "common", "foo", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_class(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_bool(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_sens(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_cat(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_catset(CuTest *tc) { + char *line[] = {"(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_sid(CuTest *tc) { + char *line[] = {"(", "sid", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_macro(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_context(CuTest *tc) { + char *line[] = {"(", "context", "con", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_level(CuTest *tc) { + char *line[] = {"(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_policycap(CuTest *tc) { + char *line[] = {"(", "policycap", "foo", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_perm(CuTest *tc) { + char *line[] = {"(", "class", "foo", "(", "read", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_catalias(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_sensalias(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_tunable(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "false", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_disable_children_helper_unknown(CuTest *tc) { + char *line[] = {"(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + uint32_t finished = 0; + + int rc = __cil_disable_children_helper(test_db->ast->root->cl_head, &finished, NULL); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + + +/* + __cil_resolve_ast_node_helper test cases +*/ + +void test_cil_resolve_ast_node_helper_call1(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_call1_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "m", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_call2(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_call2_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "foo", "extra", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_boolif(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", + "(", "boolean", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "booleanif", "(", "and", "foo", "bar", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_boolif_neg(CuTest *tc) { + char *line[] = {"(", "boolean", "foo", "true", ")", + "(", "boolean", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "booleanif", "(", "and", "dne", "N/A", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_tunif(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "foo", "bar", ")", + "(", "false", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_tunif_neg(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", + "(", "tunable", "bar", "false", ")", + "(", "class", "baz", "(", "read", ")", ")", + "(", "tunableif", "(", "and", "dne", "N/A", ")", + "(", "true", + "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catorder(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryorder", "(", "c0", "c1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catorder_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryorder", "(", "c8", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_dominance(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_dominance_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "sensitivity", "s2", ")", + "(", "dominance", "(", "s0", "s6", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_roleallow(CuTest *tc) { + char *line[] = {"(", "role", "foo", ")", \ + "(", "role", "bar", ")", \ + "(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_roleallow_neg(CuTest *tc) { + char *line[] = {"(", "role", "foo", ")", \ + "(", "roleallow", "foo", "bar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_sensalias(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_sensalias_neg(CuTest *tc) { + char *line[] = {"(", "sensitivityalias", "s0", "alias", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catalias(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catalias_neg(CuTest *tc) { + char *line[] = {"(", "categoryalias", "c0", "red", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catset(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "category", "c2", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catset_catlist_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c1", ")", + "(", "categoryset", "somecats", "(", "c0", "c1", "c2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catrange(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "categoryrange", "range", "(", "c0", "c255", ")", ")", NULL}; + + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + cil_resolve_catorder(test_db->ast->root->cl_head->next->next, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + args->pass = CIL_PASS_MLS; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_catrange_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "categoryrange", "range", "(", "c255", "c0", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MLS, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_level(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "sensitivitycategory", "s0", "(", "c1", ")", ")", + "(", "level", "l2", "(", "s0", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + __cil_verify_order(test_db->dominance, test_db->ast->root, CIL_SENS); + + args->pass = CIL_PASS_MLS; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC2; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC3; + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, finished, 0); +} + +void test_cil_resolve_ast_node_helper_level_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "sensitivitycategory", "s0", "(", "c1", ")", ")", + "(", "level", "l2", "(", "s8", "(", "c1", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + __cil_verify_order(test_db->dominance, test_db->ast->root, CIL_SENS); + + args->pass = CIL_PASS_MLS; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC3; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, finished, 0); +} + +void test_cil_resolve_ast_node_helper_levelrange(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "dominance", "(", "s0", ")", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + __cil_verify_order(test_db->dominance, test_db->ast->root, CIL_SENS); + + args->pass = CIL_PASS_MLS; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC2; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC3; + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, finished, 0); +} + +void test_cil_resolve_ast_node_helper_levelrange_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "dominance", "(", "s0", ")", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "DNE", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + __cil_verify_order(test_db->dominance, test_db->ast->root, CIL_SENS); + + args->pass = CIL_PASS_MLS; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC3; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, finished, 0); +} + +void test_cil_resolve_ast_node_helper_constrain(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", "relabelto", ")", ")", + "(", "class", "dir", "(", "create", "relabelto", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "role", "r1", ")", + "(", "role", "r2", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "r2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_constrain_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", ")", ")", + "(", "class", "dir", "(", "create", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "role", "r1", ")", + "(", "role", "r2", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "r1", "r2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_mlsconstrain(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "create", "relabelto", ")", ")", + "(", "class", "dir", "(", "create", "relabelto", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "l2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "level", "h2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_mlsconstrain_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", ")", ")", + "(", "class", "dir", "(", "read", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c1", ")", + "(", "level", "l2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "level", "h2", "(", "s0", "(", "c1", ")", ")", ")", + "(", "mlsconstrain", "(", "file", "(", "create", "relabelto", ")", ")", "(", "eq", "l2", "h2", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_context(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + __cil_verify_order(test_db->dominance, test_db->ast->root, CIL_SENS); + + args->pass = CIL_PASS_MLS; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC3; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, finished, 0); +} + +void test_cil_resolve_ast_node_helper_context_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", + "(", "system_u", "object_r", "netif_t", "DNE", "high", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC1, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + __cil_verify_order(test_db->catorder, test_db->ast->root, CIL_CAT); + + __cil_verify_order(test_db->dominance, test_db->ast->root, CIL_SENS); + + args->pass = CIL_PASS_MLS; + cil_tree_walk(test_db->ast->root, __cil_resolve_ast_node_helper, NULL, NULL, args); + + args->pass = CIL_PASS_MISC3; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, finished, 0); +} + +void test_cil_resolve_ast_node_helper_senscat(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s1", "(", "c0", "c255", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_senscat_neg(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "sensitivity", "s1", ")", + "(", "dominance", "(", "s0", "s1", ")", ")", + "(", "category", "c0", ")", + "(", "category", "c255", ")", + "(", "categoryorder", "(", "c0", "c255", ")", ")", + "(", "sensitivitycategory", "s5", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_roletransition(CuTest *tc) { + char *line[] = {"(", "role", "foo_r", ")", + "(", "type", "bar_t", ")", + "(", "role", "foobar_r", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_roletransition_srcdecl_neg(CuTest *tc) { + char *line[] = {"(", "type", "bar_t", ")", + "(", "role", "foobar_r", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_roletransition_tgtdecl_neg(CuTest *tc) { + char *line[] = {"(", "role", "foo_r", ")", + "(", "role", "foobar_r", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_roletransition_resultdecl_neg(CuTest *tc) { + char *line[] = {"(", "role", "foo_r", ")", + "(", "type", "bar_t", ")", + "(", "class", "process", "(", "transition", ")", ")", + "(", "roletransition", "foo_r", "bar_t", "process", "foobar_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typeattributeset(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "type", "type_t", ")", + "(", "type", "type_tt", ")", + "(", "typeattributeset", "attrs", "(", "type_t", "type_tt", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typeattributeset_undef_type_neg(CuTest *tc) { + char *line[] = {"(", "typeattribute", "attrs", ")", + "(", "type", "type_t", ")", + "(", "typeattributeset", "attrs", "(", "not", "t_t", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typealias(CuTest *tc) { + char *line[] = {"(", "block", "foo", + "(", "typealias", ".foo.test", "type_t", ")", + "(", "type", "test", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typealias_notype_neg(CuTest *tc) { + char *line[] = {"(", "block", "bar", + "(", "typealias", ".bar.test", "type_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typebounds(CuTest *tc) { + char *line[] = {"(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typebounds_neg(CuTest *tc) { + char *line[] = {"(", "type", "type_b", ")", + "(", "typebounds", "type_a", "type_b", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typepermissive(CuTest *tc) { + char *line[] = {"(", "type", "type_a", ")", + "(", "typepermissive", "type_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_typepermissive_neg(CuTest *tc) { + char *line[] = {"(", "type", "type_b", ")", + "(", "typepermissive", "type_a", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_rangetransition(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_a", "type_b", "class_", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_rangetransition_neg(CuTest *tc) { + char *line[] = {"(", "class", "class_", "(", "read", ")", ")", + "(", "type", "type_a", ")", + "(", "type", "type_b", ")", + "(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "rangetransition", "type_DNE", "type_b", "class_", "(", "low", "high", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_nametypetransition(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "type", "foobar", ")", + "(", "nametypetransition", "str", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_nametypetransition_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "type", "foobar", ")", + "(", "nametypetransition", "str", "foo", "bar", "file", "foobarrr", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_avrule(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_avrule_src_nores_neg(CuTest *tc) { + char *line[] = {"(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_avrule_tgt_nores_neg(CuTest *tc) { + char *line[] = {"(", "type", "test", ")", + "(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_avrule_class_nores_neg(CuTest *tc) { + char *line[] = {"(", "type", "test", ")", + "(", "type", "foo", ")", + "(", "allow", "test", "foo", "(", "bar", "(", "read", "write", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_avrule_datum_null_neg(CuTest *tc) { + char *line[] = {"(", "class", "bar", "(", "read", "write", "open", ")", ")", + "(", "type", "test", ")", "(", "type", "foo", ")", + "(", "allow", "test", "foo", "(", "bar", "(","fake", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_type_rule_transition(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_type_rule_transition_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typetransition", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_type_rule_change(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_type_rule_change_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typechange", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_type_rule_member(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_type_rule_member_neg(CuTest *tc) { + char *line[] = {"(", "type", "foo", ")", + "(", "class", "file", "(", "write", ")", ")", + "(", "type", "foobar", ")", + "(", "typemember", "foo", "bar", "file", "foobar", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_userbounds(CuTest *tc) { + char *line[] = {"(", "user", "user1", ")", + "(", "user", "user2", ")", + "(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_userbounds_neg(CuTest *tc) { + char *line[] = {"(", "user", "user1", ")", + "(", "userbounds", "user1", "user2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_roletype(CuTest *tc) { + char *line[] = {"(", "role", "admin_r", ")", + "(", "type", "admin_t", ")", + "(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_roletype_role_neg(CuTest *tc) { + char *line[] = {"(", "type", "admin_t", ")", + "(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_roletype_type_neg(CuTest *tc) { + char *line[] = {"(", "role", "admin_r", ")", + "(", "roletype", "admin_r", "admin_t", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_userrole(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_userrole_user_neg(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_userrole_role_neg(CuTest *tc) { + char *line[] = {"(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_userlevel(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "userlevel", "foo_u", "low", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_userlevel_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "userlevel", "DNE", "low", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_userrange(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", + "(", "userrange", "foo_u", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_userrange_neg(CuTest *tc) { + char *line[] = {"(", "user", "foo_u", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "levelrange", "range", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", + "(", "userrange", "DNE", "range", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + +void test_cil_resolve_ast_node_helper_filecon(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "filecon", "root", "path", "file", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_filecon_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "filecon", "root", "path", "file", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_portcon(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "portcon", "udp", "25", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_portcon_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "portcon", "udp", "25", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_genfscon(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "genfscon", "type", "path", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_genfscon_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "genfscon", "type", "path", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_nodecon(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "nodecon", "ip", "ip", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_nodecon_ipaddr_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "ipaddr", "netmask", "192.168.1.1", ")", + "(", "nodecon", "ipp", "netmask", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_nodecon_netmask_neg(CuTest *tc) { + char *line[] = {"(", "user", "user_u", ")", + "(", "role", "role_r", ")", + "(", "type", "type_t", ")", + "(", "category", "c0", ")", + "(", "sensitivity", "s0", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "context", "con", "(", "user_u", "role_r", "type_t", "(", "low", "high", ")", ")", ")", + "(", "ipaddr", "ip", "192.168.1.1", ")", + "(", "ipaddr", "netmask", "192.168.1.1", ")", + "(", "nodecon", "ip", "nnetmask", "foo", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_netifcon(CuTest *tc) { + char *line[] = {"(", "context", "if_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "context", "packet_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_netifcon_neg(CuTest *tc) { + char *line[] = {"(", "context", "if_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_pirqcon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pirqcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_pirqcon_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pirqcon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_iomemcon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "iomemcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_iomemcon_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "iomemcon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_ioportcon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "ioportcon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_ioportcon_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "ioportcon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_pcidevicecon(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pcidevicecon", "1", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_pcidevicecon_neg(CuTest *tc) { + char *line[] = {"(", "context", "con", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "pcidevicecon", "1", "dne", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_fsuse(CuTest *tc) { + char *line[] = {"(", "sensitivity", "s0", ")", + "(", "category", "c0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "user", "system_u", ")", + "(", "role", "object_r", ")", + "(", "type", "netif_t", ")", + "(", "context", "con", "(", "system_u", "object_r", "netif_t", "(", "low", "high", ")", ")", ")", + "(", "fsuse", "xattr", "ext3", "con", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_fsuse_neg(CuTest *tc) { + char *line[] = {"(", "context", "if_default", "(", "system_u", "object_r", "etc_t", "(", "low", "high", ")", ")", ")", + "(", "netifcon", "eth0", "if_default", "packet_default", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_sidcontext(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "level", "low", "(", "s0", "(", "c0", ")", ")", ")", + "(", "level", "high", "(", "s0", "(", "c0", ")", ")", ")", + "(", "sid", "test", "(", "blah_u", "blah_r", "blah_t", "(", "low", "high", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_sidcontext_neg(CuTest *tc) { + char *line[] = {"(", "category", "c0", ")", + "(", "categoryorder", "(", "c0", ")", ")", + "(", "sensitivity", "s0", ")", + "(", "sensitivitycategory", "s0", "(", "c0", ")", ")", + "(", "type", "blah_t", ")", + "(", "role", "blah_r", ")", + "(", "user", "blah_u", ")", + "(", "sidcontext", "test", "(", "", "blah_r", "blah_t", "(", "(", "s0", "(", "c0", ")", ")", "(", "s0", "(", "c0", ")", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next->next->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_blockinherit(CuTest *tc) { + char *line[] = {"(", "block", "baz", "(", "type", "foo", ")", ")", + "(", "block", "bar", "(", "type", "a", ")", + "(", "blockinherit", "baz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_BLKIN, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_classcommon(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", ")", ")", + "(", "common", "file", "(", "write", ")", ")", + "(", "classcommon", "file", "file", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_classcommon_neg(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", ")", ")", + "(", "classcommon", "file", "file", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_rolebounds(CuTest *tc) { + char *line[] = {"(", "role", "role1", ")", + "(", "role", "role2", ")", + "(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_rolebounds_neg(CuTest *tc) { + char *line[] = {"(", "role", "role1", ")", + "(", "rolebounds", "role1", "role2", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ENOENT, rc); +} + + +void test_cil_resolve_ast_node_helper_callstack(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_tree_node *test_ast_node_call; + cil_tree_node_init(&test_ast_node_call); + test_ast_node_call->flavor = CIL_CALL; + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_call(CuTest *tc) { + char *line[] = {"(", "call", "mm", "(", "foo", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_tree_node *test_ast_node_call; + cil_tree_node_init(&test_ast_node_call); + test_ast_node_call->flavor = CIL_CALL; + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_optional(CuTest *tc) { + char *line[] = {"(", "optional", "opt", "(", "allow", "foo", "bar", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_tree_node *test_ast_node_opt; + cil_tree_node_init(&test_ast_node_opt); + test_ast_node_opt->flavor = CIL_OPTIONAL; + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + // set optional to disabled + ((struct cil_symtab_datum *)test_db->ast->root->cl_head->data)->state = CIL_STATE_DISABLED; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_macro(CuTest *tc) { + char *line[] = {"(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_optstack(CuTest *tc) { + char *line[] = {"(", "class", "baz", "(", "read", ")", ")", + "(", "type", "foo", ")", + "(", "type", "bar", ")", + "(", "optional", "opt", "(", "allow", "foo", "bar", "(", "baz", "(", "read", ")", ")", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_tree_node *test_ast_node_opt; + cil_tree_node_init(&test_ast_node_opt); + test_ast_node_opt->flavor = CIL_OPTIONAL; + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} + +void test_cil_resolve_ast_node_helper_optstack_tunable_neg(CuTest *tc) { + char *line[] = {"(", "tunable", "foo", "true", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node_opt; + cil_tree_node_init(&test_ast_node_opt); + test_ast_node_opt->flavor = CIL_OPTIONAL; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, test_ast_node_opt, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head, &finished, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_ast_node_helper_optstack_macro_neg(CuTest *tc) { + char *line[] = {"(", "type", "qaz", ")", + "(", "class", "file", "(", "read", ")", ")", + "(", "macro", "mm", "(", "(", "type", "a", ")", ")", + "(", "type", "b", ")", + "(", "allow", "a", "b", "(", "file", "(", "read", ")", ")", ")", ")", + "(", "call", "mm", "(", "qaz", ")", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node_opt; + cil_tree_node_init(&test_ast_node_opt); + test_ast_node_opt->flavor = CIL_OPTIONAL; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_CALL1, &changed, NULL, test_ast_node_opt, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + cil_resolve_call1(test_db->ast->root->cl_head->next->next, args); + + args->pass = CIL_PASS_CALL2; + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); + CuAssertIntEquals(tc, 0, finished); +} + +void test_cil_resolve_ast_node_helper_nodenull_neg(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_TIF, &changed, NULL, NULL, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(NULL, &finished, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_ast_node_helper_extraargsnull_neg(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, NULL); + CuAssertIntEquals(tc, 0, finished); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_ast_node_helper_dbflavor_neg(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_ast_node_helper_pass_neg(CuTest *tc) { + char *line[] = {"(", "role", "staff_r", ")", + "(", "user", "staff_u", ")", + "(", "userrole", "staff_u", "staff_r", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + uint32_t finished = 0; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC3, &changed, NULL, NULL, NULL); + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_ERR, rc); +} + +void test_cil_resolve_ast_node_helper_optfailedtoresolve(CuTest *tc) { + char *line[] = {"(", "class", "file", "(", "read", ")", ")", + "(", "classcommon", "file", "file", ")", NULL}; + + struct cil_tree *test_tree; + gen_test_tree(&test_tree, line); + + struct cil_db *test_db; + cil_db_init(&test_db); + + struct cil_optional *opt; + cil_optional_init(&opt); + + struct cil_tree_node *test_ast_node_opt; + cil_tree_node_init(&test_ast_node_opt); + test_ast_node_opt->flavor = CIL_OPTIONAL; + test_ast_node_opt->data = opt; + + uint32_t changed = CIL_FALSE; + struct cil_args_resolve *args = gen_resolve_args(test_db, CIL_PASS_MISC2, &changed, NULL, test_ast_node_opt, NULL); + + uint32_t finished = 0; + + cil_build_ast(test_db, test_tree->root, test_db->ast->root); + + int rc = __cil_resolve_ast_node_helper(test_db->ast->root->cl_head->next, &finished, args); + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertIntEquals(tc, 0, finished); +} + diff --git a/kernel/libsepol/cil/test/unit/test_cil_resolve_ast.h b/kernel/libsepol/cil/test/unit/test_cil_resolve_ast.h new file mode 100644 index 00000000..394efde5 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_resolve_ast.h @@ -0,0 +1,578 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_RESOLVE_AST_H_ +#define TEST_CIL_RESOLVE_AST_H_ + +#include "CuTest.h" + +void test_cil_resolve_name(CuTest *); +void test_cil_resolve_name_invalid_type_neg(CuTest *); + +void test_cil_resolve_ast_curr_null_neg(CuTest *); + + +/* + cil_resolve test cases +*/ + +void test_cil_resolve_roleallow(CuTest *); +void test_cil_resolve_roleallow_srcdecl_neg(CuTest *); +void test_cil_resolve_roleallow_tgtdecl_neg(CuTest *); + +void test_cil_resolve_rolebounds(CuTest *tc); +void test_cil_resolve_rolebounds_exists_neg(CuTest *tc); +void test_cil_resolve_rolebounds_role1_neg(CuTest *tc); +void test_cil_resolve_rolebounds_role2_neg(CuTest *tc); + +void test_cil_resolve_sensalias(CuTest *); +void test_cil_resolve_sensalias_sensdecl_neg(CuTest *); + +void test_cil_resolve_catalias(CuTest *); +void test_cil_resolve_catalias_catdecl_neg(CuTest *); + +void test_cil_resolve_catorder(CuTest *); +void test_cil_resolve_catorder_neg(CuTest *); + +void test_cil_resolve_dominance(CuTest *); +void test_cil_resolve_dominance_neg(CuTest *); + +void test_cil_resolve_cat_list(CuTest *); +void test_cil_resolve_cat_list_catlistnull_neg(CuTest *); +void test_cil_resolve_cat_list_rescatlistnull_neg(CuTest *); +void test_cil_resolve_cat_list_catrange(CuTest *); +void test_cil_resolve_cat_list_catrange_neg(CuTest *); +void test_cil_resolve_cat_list_catname_neg(CuTest *); + +void test_cil_resolve_catset(CuTest *); +void test_cil_resolve_catset_catlist_neg(CuTest *); + +void test_cil_resolve_catrange(CuTest *); +void test_cil_resolve_catrange_catloworder_neg(CuTest *); +void test_cil_resolve_catrange_cathighorder_neg(CuTest *); +void test_cil_resolve_catrange_cat1_neg(CuTest *); +void test_cil_resolve_catrange_cat2_neg(CuTest *); + +void test_cil_resolve_senscat(CuTest *); +void test_cil_resolve_senscat_catrange_neg(CuTest *); +void test_cil_resolve_senscat_catsetname(CuTest *); +void test_cil_resolve_senscat_catsetname_neg(CuTest *); +void test_cil_resolve_senscat_sublist(CuTest *); +void test_cil_resolve_senscat_missingsens_neg(CuTest *); +void test_cil_resolve_senscat_sublist_neg(CuTest *); +void test_cil_resolve_senscat_category_neg(CuTest *); +void test_cil_resolve_senscat_currrangecat(CuTest *); +void test_cil_resolve_senscat_currrangecat_neg(CuTest *); + +void test_cil_resolve_level(CuTest *); +void test_cil_resolve_level_catlist(CuTest *); +void test_cil_resolve_level_catset(CuTest *); +void test_cil_resolve_level_catset_name_neg(CuTest *); +void test_cil_resolve_level_sens_neg(CuTest *); +void test_cil_resolve_level_cat_neg(CuTest *); +void test_cil_resolve_level_senscat_neg(CuTest *); + +void test_cil_resolve_levelrange_namedlvl(CuTest *); +void test_cil_resolve_levelrange_namedlvl_low_neg(CuTest *); +void test_cil_resolve_levelrange_namedlvl_high_neg(CuTest *); +void test_cil_resolve_levelrange_anonlvl(CuTest *); +void test_cil_resolve_levelrange_anonlvl_low_neg(CuTest *); +void test_cil_resolve_levelrange_anonlvl_high_neg(CuTest *); + +void test_cil_resolve_constrain(CuTest *); +void test_cil_resolve_constrain_class_neg(CuTest *); +void test_cil_resolve_constrain_perm_neg(CuTest *); +void test_cil_resolve_constrain_perm_resolve_neg(CuTest *); + +void test_cil_resolve_context(CuTest *); +void test_cil_resolve_context_macro(CuTest *); +void test_cil_resolve_context_macro_neg(CuTest *); +void test_cil_resolve_context_namedrange(CuTest *); +void test_cil_resolve_context_namedrange_neg(CuTest *); +void test_cil_resolve_context_macro_namedrange_anon(CuTest *); +void test_cil_resolve_context_user_neg(CuTest *); +void test_cil_resolve_context_role_neg(CuTest *); +void test_cil_resolve_context_type_neg(CuTest *); +void test_cil_resolve_context_anon_level_neg(CuTest *); + +void test_cil_resolve_roletransition(CuTest *); +void test_cil_resolve_roletransition_srcdecl_neg(CuTest *); +void test_cil_resolve_roletransition_tgtdecl_neg(CuTest *); +void test_cil_resolve_roletransition_resultdecl_neg(CuTest *); + +void test_cil_resolve_typeattributeset_type_in_multiple_attrs(CuTest *); +void test_cil_resolve_typeattributeset_multiple_excludes_with_not(CuTest *); +void test_cil_resolve_typeattributeset_multiple_types_with_and(CuTest *); +void test_cil_resolve_typeattributeset_using_attr(CuTest *); +void test_cil_resolve_typeattributeset_name_neg(CuTest *); +void test_cil_resolve_typeattributeset_undef_type_neg(CuTest *); +void test_cil_resolve_typeattributeset_not(CuTest *); +void test_cil_resolve_typeattributeset_undef_type_not_neg(CuTest *); + +void test_cil_resolve_typealias(CuTest *); +void test_cil_resolve_typealias_neg(CuTest *); + +void test_cil_resolve_typebounds(CuTest *); +void test_cil_resolve_typebounds_repeatbind_neg(CuTest *); +void test_cil_resolve_typebounds_type1_neg(CuTest *); +void test_cil_resolve_typebounds_type2_neg(CuTest *); + +void test_cil_resolve_typepermissive(CuTest *); +void test_cil_resolve_typepermissive_neg(CuTest *); + +void test_cil_resolve_nametypetransition(CuTest *); +void test_cil_resolve_nametypetransition_src_neg(CuTest *); +void test_cil_resolve_nametypetransition_tgt_neg(CuTest *); +void test_cil_resolve_nametypetransition_class_neg(CuTest *); +void test_cil_resolve_nametypetransition_dest_neg(CuTest *); + +void test_cil_resolve_rangetransition(CuTest *); +void test_cil_resolve_rangetransition_namedrange(CuTest *); +void test_cil_resolve_rangetransition_namedrange_anon(CuTest *); +void test_cil_resolve_rangetransition_namedrange_anon_neg(CuTest *); +void test_cil_resolve_rangetransition_namedrange_neg(CuTest *); +void test_cil_resolve_rangetransition_type1_neg(CuTest *); +void test_cil_resolve_rangetransition_type2_neg(CuTest *); +void test_cil_resolve_rangetransition_class_neg(CuTest *); +void test_cil_resolve_rangetransition_call_level_l_anon(CuTest *); +void test_cil_resolve_rangetransition_call_level_l_anon_neg(CuTest *); +void test_cil_resolve_rangetransition_call_level_h_anon(CuTest *); +void test_cil_resolve_rangetransition_call_level_h_anon_neg(CuTest *); +void test_cil_resolve_rangetransition_level_l_neg(CuTest *); +void test_cil_resolve_rangetransition_level_h_neg(CuTest *); +void test_cil_resolve_rangetransition_anon_level_l(CuTest *); +void test_cil_resolve_rangetransition_anon_level_l_neg(CuTest *); +void test_cil_resolve_rangetransition_anon_level_h(CuTest *); +void test_cil_resolve_rangetransition_anon_level_h_neg(CuTest *); + +void test_cil_resolve_classcommon(CuTest *); +void test_cil_resolve_classcommon_no_class_neg(CuTest *); +void test_cil_resolve_classcommon_neg(CuTest *); +void test_cil_resolve_classcommon_no_common_neg(CuTest *); + +void test_cil_resolve_classmapping_named(CuTest *); +void test_cil_resolve_classmapping_anon(CuTest *); +void test_cil_resolve_classmapping_anon_inmacro(CuTest *); +void test_cil_resolve_classmapping_anon_inmacro_neg(CuTest *); +void test_cil_resolve_classmapping_named_classmapname_neg(CuTest *); +void test_cil_resolve_classmapping_anon_classmapname_neg(CuTest *); +void test_cil_resolve_classmapping_anon_permset_neg(CuTest *); + +void test_cil_resolve_classpermset_named(CuTest *); +void test_cil_resolve_classpermset_named_namedpermlist(CuTest *); +void test_cil_resolve_classpermset_named_permlist_neg(CuTest *); +void test_cil_resolve_classpermset_named_unnamedcps_neg(CuTest *); +void test_cil_resolve_classpermset_anon(CuTest *); +void test_cil_resolve_classpermset_anon_namedpermlist(CuTest *); +void test_cil_resolve_classpermset_anon_permlist_neg(CuTest *); + +void test_cil_resolve_avrule(CuTest *); +void test_cil_resolve_avrule_permset(CuTest *); +void test_cil_resolve_avrule_permset_neg(CuTest *); +void test_cil_resolve_avrule_permset_permdne_neg(CuTest *); +void test_cil_resolve_avrule_firsttype_neg(CuTest *); +void test_cil_resolve_avrule_secondtype_neg(CuTest *); +void test_cil_resolve_avrule_class_neg(CuTest *); +void test_cil_resolve_avrule_perm_neg(CuTest *); + +void test_cil_resolve_type_rule_transition(CuTest *); +void test_cil_resolve_type_rule_transition_srcdecl_neg(CuTest *); +void test_cil_resolve_type_rule_transition_tgtdecl_neg(CuTest *); +void test_cil_resolve_type_rule_transition_objdecl_neg(CuTest *); +void test_cil_resolve_type_rule_transition_resultdecl_neg(CuTest *); + +void test_cil_resolve_type_rule_change(CuTest *); +void test_cil_resolve_type_rule_change_srcdecl_neg(CuTest *); +void test_cil_resolve_type_rule_change_tgtdecl_neg(CuTest *); +void test_cil_resolve_type_rule_change_objdecl_neg(CuTest *); +void test_cil_resolve_type_rule_change_resultdecl_neg(CuTest *); + +void test_cil_resolve_type_rule_member(CuTest *); +void test_cil_resolve_type_rule_member_srcdecl_neg(CuTest *); +void test_cil_resolve_type_rule_member_tgtdecl_neg(CuTest *); +void test_cil_resolve_type_rule_member_objdecl_neg(CuTest *); +void test_cil_resolve_type_rule_member_resultdecl_neg(CuTest *); + +void test_cil_resolve_filecon(CuTest *); +void test_cil_resolve_filecon_neg(CuTest *); +void test_cil_resolve_filecon_anon_context(CuTest *); +void test_cil_resolve_filecon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_filecon(CuTest *tc); +void test_cil_resolve_ast_node_helper_filecon_neg(CuTest *tc); + +void test_cil_resolve_portcon(CuTest *); +void test_cil_resolve_portcon_neg(CuTest *); +void test_cil_resolve_portcon_anon_context(CuTest *); +void test_cil_resolve_portcon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_portcon(CuTest *tc); +void test_cil_resolve_ast_node_helper_portcon_neg(CuTest *tc); + +void test_cil_resolve_genfscon(CuTest *); +void test_cil_resolve_genfscon_neg(CuTest *); +void test_cil_resolve_genfscon_anon_context(CuTest *); +void test_cil_resolve_genfscon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_genfscon(CuTest *tc); +void test_cil_resolve_ast_node_helper_genfscon_neg(CuTest *tc); + +void test_cil_resolve_nodecon_ipv4(CuTest *); +void test_cil_resolve_nodecon_ipv6(CuTest *); +void test_cil_resolve_nodecon_anonipaddr_ipv4(CuTest *); +void test_cil_resolve_nodecon_anonnetmask_ipv4(CuTest *); +void test_cil_resolve_nodecon_anonipaddr_ipv6(CuTest *); +void test_cil_resolve_nodecon_anonnetmask_ipv6(CuTest *); +void test_cil_resolve_nodecon_diffipfam_neg(CuTest *); +void test_cil_resolve_nodecon_context_neg(CuTest *); +void test_cil_resolve_nodecon_ipaddr_neg(CuTest *); +void test_cil_resolve_nodecon_netmask_neg(CuTest *); +void test_cil_resolve_nodecon_anon_context(CuTest *); +void test_cil_resolve_nodecon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_nodecon(CuTest *tc); +void test_cil_resolve_ast_node_helper_nodecon_ipaddr_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_nodecon_netmask_neg(CuTest *tc); + +void test_cil_resolve_netifcon(CuTest *); +void test_cil_resolve_netifcon_otf_neg(CuTest *); +void test_cil_resolve_netifcon_interface_neg(CuTest *); +void test_cil_resolve_netifcon_unnamed(CuTest *); +void test_cil_resolve_netifcon_unnamed_packet_neg(CuTest *); +void test_cil_resolve_netifcon_unnamed_otf_neg(CuTest *); +void test_cil_resolve_ast_node_helper_netifcon(CuTest *tc); +void test_cil_resolve_ast_node_helper_netifcon_neg(CuTest *tc); + +void test_cil_resolve_pirqcon(CuTest *); +void test_cil_resolve_pirqcon_context_neg(CuTest *); +void test_cil_resolve_pirqcon_anon_context(CuTest *); +void test_cil_resolve_pirqcon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_pirqcon(CuTest *tc); +void test_cil_resolve_ast_node_helper_pirqcon_neg(CuTest *tc); + +void test_cil_resolve_iomemcon(CuTest *); +void test_cil_resolve_iomemcon_context_neg(CuTest *); +void test_cil_resolve_iomemcon_anon_context(CuTest *); +void test_cil_resolve_iomemcon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_iomemcon(CuTest *tc); +void test_cil_resolve_ast_node_helper_iomemcon_neg(CuTest *tc); + +void test_cil_resolve_ioportcon(CuTest *); +void test_cil_resolve_ioportcon_context_neg(CuTest *); +void test_cil_resolve_ioportcon_anon_context(CuTest *); +void test_cil_resolve_ioportcon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_ioportcon(CuTest *tc); +void test_cil_resolve_ast_node_helper_ioportcon_neg(CuTest *tc); + +void test_cil_resolve_pcidevicecon(CuTest *); +void test_cil_resolve_pcidevicecon_context_neg(CuTest *); +void test_cil_resolve_pcidevicecon_anon_context(CuTest *); +void test_cil_resolve_pcidevicecon_anon_context_neg(CuTest *); +void test_cil_resolve_ast_node_helper_pcidevicecon(CuTest *tc); +void test_cil_resolve_ast_node_helper_pcidevicecon_neg(CuTest *tc); + +void test_cil_resolve_fsuse(CuTest *); +void test_cil_resolve_fsuse_neg(CuTest *); +void test_cil_resolve_fsuse_anon(CuTest *); +void test_cil_resolve_fsuse_anon_neg(CuTest *); +void test_cil_resolve_ast_node_helper_fsuse(CuTest *tc); +void test_cil_resolve_ast_node_helper_fsuse_neg(CuTest *tc); + +void test_cil_resolve_sidcontext(CuTest *); +void test_cil_resolve_sidcontext_named_levels(CuTest *); +void test_cil_resolve_sidcontext_named_context(CuTest *); +void test_cil_resolve_sidcontext_named_context_wrongname_neg(CuTest *tc); +void test_cil_resolve_sidcontext_named_context_invaliduser_neg(CuTest *tc); +void test_cil_resolve_sidcontext_named_context_sidcontextnull_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_sidcontext(CuTest *tc); +void test_cil_resolve_ast_node_helper_sidcontext_neg(CuTest *tc); + +void test_cil_resolve_blockinherit(CuTest *); +void test_cil_resolve_blockinherit_blockstrdne_neg(CuTest *); +void test_cil_resolve_ast_node_helper_blockinherit(CuTest *tc); + +void test_cil_resolve_in_block(CuTest *); +void test_cil_resolve_in_blockstrdne_neg(CuTest *); +void test_cil_resolve_in_macro(CuTest *); +void test_cil_resolve_in_optional(CuTest *); + +void test_cil_resolve_call1_noparam(CuTest *); +void test_cil_resolve_call1_type(CuTest *); +void test_cil_resolve_call1_role(CuTest *); +void test_cil_resolve_call1_user(CuTest *); +void test_cil_resolve_call1_sens(CuTest *); +void test_cil_resolve_call1_cat(CuTest *); +void test_cil_resolve_call1_catset(CuTest *); +void test_cil_resolve_call1_catset_anon(CuTest *); +void test_cil_resolve_call1_catset_anon_neg(CuTest *); +void test_cil_resolve_call1_level(CuTest *); +void test_cil_resolve_call1_class(CuTest *); +void test_cil_resolve_call1_classmap(CuTest *); +void test_cil_resolve_call1_permset(CuTest *); +void test_cil_resolve_call1_permset_anon(CuTest *); +void test_cil_resolve_call1_classpermset_named(CuTest *); +void test_cil_resolve_call1_classpermset_anon(CuTest *); +void test_cil_resolve_call1_classpermset_anon_neg(CuTest *); +void test_cil_resolve_call1_level(CuTest *); +void test_cil_resolve_call1_level_anon(CuTest *); +void test_cil_resolve_call1_level_anon_neg(CuTest *); +void test_cil_resolve_call1_ipaddr(CuTest *); +void test_cil_resolve_call1_ipaddr_anon(CuTest *); +void test_cil_resolve_call1_ipaddr_anon_neg(CuTest *); +void test_cil_resolve_call1_unknown_neg(CuTest *); +void test_cil_resolve_call1_unknowncall_neg(CuTest *); +void test_cil_resolve_call1_extraargs_neg(CuTest *); +void test_cil_resolve_call1_copy_dup(CuTest *); +void test_cil_resolve_call1_missing_arg_neg(CuTest *); +void test_cil_resolve_call1_paramsflavor_neg(CuTest *); +void test_cil_resolve_call1_unknownflavor_neg(CuTest *); + +void test_cil_resolve_call2_type(CuTest *); +void test_cil_resolve_call2_role(CuTest *); +void test_cil_resolve_call2_user(CuTest *); +void test_cil_resolve_call2_sens(CuTest *); +void test_cil_resolve_call2_cat(CuTest *); +void test_cil_resolve_call2_catset(CuTest *); +void test_cil_resolve_call2_catset_anon(CuTest *); +void test_cil_resolve_call2_permset(CuTest *); +void test_cil_resolve_call2_permset_anon(CuTest *); +void test_cil_resolve_call2_classpermset_named(CuTest *); +void test_cil_resolve_call2_classpermset_anon(CuTest *); +void test_cil_resolve_call2_class(CuTest *); +void test_cil_resolve_call2_classmap(CuTest *); +void test_cil_resolve_call2_level(CuTest *); +void test_cil_resolve_call2_level_anon(CuTest *); +void test_cil_resolve_call2_ipaddr(CuTest *); +void test_cil_resolve_call2_ipaddr_anon(CuTest *); +void test_cil_resolve_call2_unknown_neg(CuTest *); + +void test_cil_resolve_name_call_args(CuTest *); +void test_cil_resolve_name_call_args_multipleparams(CuTest *); +void test_cil_resolve_name_call_args_diffflavor(CuTest *); +void test_cil_resolve_name_call_args_callnull_neg(CuTest *); +void test_cil_resolve_name_call_args_namenull_neg(CuTest *); +void test_cil_resolve_name_call_args_callargsnull_neg(CuTest *); +void test_cil_resolve_name_call_args_name_neg(CuTest *); + +void test_cil_resolve_expr_stack_bools(CuTest *); +void test_cil_resolve_expr_stack_tunables(CuTest *); +void test_cil_resolve_expr_stack_type(CuTest *); +void test_cil_resolve_expr_stack_role(CuTest *); +void test_cil_resolve_expr_stack_user(CuTest *); +void test_cil_resolve_expr_stack_neg(CuTest *); +void test_cil_resolve_expr_stack_emptystr_neg(CuTest *); + +void test_cil_resolve_boolif(CuTest *); +void test_cil_resolve_boolif_neg(CuTest *); + +void test_cil_evaluate_expr_stack_and(CuTest *); +void test_cil_evaluate_expr_stack_not(CuTest *); +void test_cil_evaluate_expr_stack_or(CuTest *); +void test_cil_evaluate_expr_stack_xor(CuTest *); +void test_cil_evaluate_expr_stack_eq(CuTest *); +void test_cil_evaluate_expr_stack_neq(CuTest *); +void test_cil_evaluate_expr_stack_oper1(CuTest *); +void test_cil_evaluate_expr_stack_oper2(CuTest *); +void test_cil_evaluate_expr_stack_neg(CuTest *); + +void test_cil_resolve_tunif_false(CuTest *); +void test_cil_resolve_tunif_true(CuTest *); +void test_cil_resolve_tunif_resolveexpr_neg(CuTest *); +void test_cil_resolve_tunif_evaluateexpr_neg(CuTest *); + +void test_cil_resolve_userbounds(CuTest *tc); +void test_cil_resolve_userbounds_exists_neg(CuTest *tc); +void test_cil_resolve_userbounds_user1_neg(CuTest *tc); +void test_cil_resolve_userbounds_user2_neg(CuTest *tc); + +void test_cil_resolve_roletype(CuTest *tc); +void test_cil_resolve_roletype_type_neg(CuTest *tc); +void test_cil_resolve_roletype_role_neg(CuTest *tc); + +void test_cil_resolve_userrole(CuTest *tc); +void test_cil_resolve_userrole_user_neg(CuTest *tc); +void test_cil_resolve_userrole_role_neg(CuTest *tc); + +void test_cil_resolve_userlevel(CuTest *tc); +void test_cil_resolve_userlevel_macro(CuTest *tc); +void test_cil_resolve_userlevel_macro_neg(CuTest *tc); +void test_cil_resolve_userlevel_level_anon(CuTest *tc); +void test_cil_resolve_userlevel_level_anon_neg(CuTest *tc); +void test_cil_resolve_userlevel_user_neg(CuTest *tc); +void test_cil_resolve_userlevel_level_neg(CuTest *tc); + +void test_cil_resolve_userrange(CuTest *tc); +void test_cil_resolve_userrange_macro(CuTest *tc); +void test_cil_resolve_userrange_macro_neg(CuTest *tc); +void test_cil_resolve_userrange_range_anon(CuTest *tc); +void test_cil_resolve_userrange_range_anon_neg(CuTest *tc); +void test_cil_resolve_userrange_user_neg(CuTest *tc); +void test_cil_resolve_userrange_range_neg(CuTest *tc); + +void test_cil_disable_children_helper_optional_enabled(CuTest *tc); +void test_cil_disable_children_helper_optional_disabled(CuTest *tc); +void test_cil_disable_children_helper_block(CuTest *tc); +void test_cil_disable_children_helper_user(CuTest *tc); +void test_cil_disable_children_helper_role(CuTest *tc); +void test_cil_disable_children_helper_type(CuTest *tc); +void test_cil_disable_children_helper_typealias(CuTest *tc); +void test_cil_disable_children_helper_common(CuTest *tc); +void test_cil_disable_children_helper_class(CuTest *tc); +void test_cil_disable_children_helper_bool(CuTest *tc); +void test_cil_disable_children_helper_sens(CuTest *tc); +void test_cil_disable_children_helper_cat(CuTest *tc); +void test_cil_disable_children_helper_catset(CuTest *tc); +void test_cil_disable_children_helper_sid(CuTest *tc); +void test_cil_disable_children_helper_macro(CuTest *tc); +void test_cil_disable_children_helper_context(CuTest *tc); +void test_cil_disable_children_helper_level(CuTest *tc); +void test_cil_disable_children_helper_policycap(CuTest *tc); +void test_cil_disable_children_helper_perm(CuTest *tc); +void test_cil_disable_children_helper_catalias(CuTest *tc); +void test_cil_disable_children_helper_sensalias(CuTest *tc); +void test_cil_disable_children_helper_tunable(CuTest *tc); +void test_cil_disable_children_helper_unknown(CuTest *tc); + +/* + __cil_resolve_ast_node_helper test cases +*/ + +void test_cil_resolve_ast_node_helper_call1(CuTest *); +void test_cil_resolve_ast_node_helper_call1_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_call2(CuTest *); +void test_cil_resolve_ast_node_helper_call2_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_boolif(CuTest *); +void test_cil_resolve_ast_node_helper_boolif_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_tunif(CuTest *); +void test_cil_resolve_ast_node_helper_tunif_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_catorder(CuTest *); +void test_cil_resolve_ast_node_helper_catorder_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_dominance(CuTest *); +void test_cil_resolve_ast_node_helper_dominance_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_roleallow(CuTest *); +void test_cil_resolve_ast_node_helper_roleallow_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_rolebounds(CuTest *tc); +void test_cil_resolve_ast_node_helper_rolebounds_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_sensalias(CuTest *); +void test_cil_resolve_ast_node_helper_sensalias_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_catalias(CuTest *); +void test_cil_resolve_ast_node_helper_catalias_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_catset(CuTest *); +void test_cil_resolve_ast_node_helper_catset_catlist_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_level(CuTest *); +void test_cil_resolve_ast_node_helper_level_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_levelrange(CuTest *); +void test_cil_resolve_ast_node_helper_levelrange_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_constrain(CuTest *); +void test_cil_resolve_ast_node_helper_constrain_neg(CuTest *); +void test_cil_resolve_ast_node_helper_mlsconstrain(CuTest *); +void test_cil_resolve_ast_node_helper_mlsconstrain_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_context(CuTest *); +void test_cil_resolve_ast_node_helper_context_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_catrange(CuTest *tc); +void test_cil_resolve_ast_node_helper_catrange_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_senscat(CuTest *tc); +void test_cil_resolve_ast_node_helper_senscat_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_roletransition(CuTest *); +void test_cil_resolve_ast_node_helper_roletransition_srcdecl_neg(CuTest *); +void test_cil_resolve_ast_node_helper_roletransition_tgtdecl_neg(CuTest *); +void test_cil_resolve_ast_node_helper_roletransition_resultdecl_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_typeattributeset(CuTest *); +void test_cil_resolve_ast_node_helper_typeattributeset_undef_type_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_typealias(CuTest *); +void test_cil_resolve_ast_node_helper_typealias_notype_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_typebounds(CuTest *); +void test_cil_resolve_ast_node_helper_typebounds_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_typepermissive(CuTest *); +void test_cil_resolve_ast_node_helper_typepermissive_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_nametypetransition(CuTest *); +void test_cil_resolve_ast_node_helper_nametypetransition_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_rangetransition(CuTest *); +void test_cil_resolve_ast_node_helper_rangetransition_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_avrule(CuTest *); +void test_cil_resolve_ast_node_helper_avrule_src_nores_neg(CuTest *); +void test_cil_resolve_ast_node_helper_avrule_tgt_nores_neg(CuTest *); +void test_cil_resolve_ast_node_helper_avrule_class_nores_neg(CuTest *); +void test_cil_resolve_ast_node_helper_avrule_datum_null_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_type_rule_transition(CuTest *); +void test_cil_resolve_ast_node_helper_type_rule_transition_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_type_rule_change(CuTest *); +void test_cil_resolve_ast_node_helper_type_rule_change_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_type_rule_member(CuTest *); +void test_cil_resolve_ast_node_helper_type_rule_member_neg(CuTest *); + +void test_cil_resolve_ast_node_helper_userbounds(CuTest *tc); +void test_cil_resolve_ast_node_helper_userbounds_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_roletype(CuTest *tc); +void test_cil_resolve_ast_node_helper_roletype_role_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_roletype_type_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_userrole(CuTest *tc); +void test_cil_resolve_ast_node_helper_userrole_user_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_userrole_role_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_userlevel(CuTest *tc); +void test_cil_resolve_ast_node_helper_userlevel_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_userlevel(CuTest *tc); +void test_cil_resolve_ast_node_helper_userlevel_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_userrange(CuTest *tc); +void test_cil_resolve_ast_node_helper_userrange_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_classcommon(CuTest *tc); +void test_cil_resolve_ast_node_helper_classcommon_neg(CuTest *tc); + +void test_cil_resolve_ast_node_helper_callstack(CuTest *tc); +void test_cil_resolve_ast_node_helper_call(CuTest *tc); +void test_cil_resolve_ast_node_helper_optional(CuTest *tc); +void test_cil_resolve_ast_node_helper_macro(CuTest *tc); +void test_cil_resolve_ast_node_helper_optstack(CuTest *tc); +void test_cil_resolve_ast_node_helper_optstack_tunable_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_optstack_macro_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_nodenull_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_extraargsnull_neg(CuTest *tc); +void test_cil_resolve_ast_node_helper_optfailedtoresolve(CuTest *tc); +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_symtab.c b/kernel/libsepol/cil/test/unit/test_cil_symtab.c new file mode 100644 index 00000000..379149ac --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_symtab.c @@ -0,0 +1,61 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "test_cil_symtab.h" + +#include "../../src/cil_tree.h" +#include "../../src/cil_symtab.h" +#include "../../src/cil_internal.h" + +void test_cil_symtab_insert(CuTest *tc) { + symtab_t *test_symtab = NULL; + char* test_name = "test"; + struct cil_block *test_block = malloc(sizeof(*test_block)); + + struct cil_tree_node *test_ast_node; + cil_tree_node_init(&test_ast_node); + + struct cil_db *test_db; + cil_db_init(&test_db); + + test_ast_node->parent = test_db->ast->root; + test_ast_node->line = 1; + + cil_symtab_array_init(test_block->symtab, cil_sym_sizes[CIL_SYM_ARRAY_BLOCK]); + + test_block->is_abstract = 0; + + cil_get_symtab(test_db, test_ast_node->parent, &test_symtab, CIL_SYM_BLOCKS); + + int rc = cil_symtab_insert(test_symtab, (hashtab_key_t)test_name, (struct cil_symtab_datum*)test_block, test_ast_node); + CuAssertIntEquals(tc, SEPOL_OK, rc); +} diff --git a/kernel/libsepol/cil/test/unit/test_cil_symtab.h b/kernel/libsepol/cil/test/unit/test_cil_symtab.h new file mode 100644 index 00000000..76053af9 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_symtab.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_SYMTAB_H_ +#define TEST_CIL_SYMTAB_H_ + +#include "CuTest.h" + +void test_cil_symtab_insert(CuTest *); + +#endif diff --git a/kernel/libsepol/cil/test/unit/test_cil_tree.c b/kernel/libsepol/cil/test/unit/test_cil_tree.c new file mode 100644 index 00000000..8bdc1135 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_tree.c @@ -0,0 +1,71 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "test_cil_tree.h" + +#include "../../src/cil_tree.h" + +void test_cil_tree_node_init(CuTest *tc) { + struct cil_tree_node *test_node; + + cil_tree_node_init(&test_node); + + CuAssertPtrNotNull(tc, test_node); + CuAssertPtrEquals(tc, NULL, test_node->cl_head); + CuAssertPtrEquals(tc, NULL, test_node->cl_tail); + CuAssertPtrEquals(tc, NULL, test_node->parent); + CuAssertPtrEquals(tc, NULL, test_node->data); + CuAssertPtrEquals(tc, NULL, test_node->next); + CuAssertIntEquals(tc, 0, test_node->flavor); + CuAssertIntEquals(tc, 0, test_node->line); + + free(test_node); +} + +void test_cil_tree_init(CuTest *tc) { + struct cil_tree *test_tree; + + int rc = cil_tree_init(&test_tree); + + CuAssertIntEquals(tc, SEPOL_OK, rc); + CuAssertPtrNotNull(tc, test_tree); + CuAssertPtrEquals(tc, NULL, test_tree->root->cl_head); + CuAssertPtrEquals(tc, NULL, test_tree->root->cl_tail); + CuAssertPtrEquals(tc, NULL, test_tree->root->parent); + CuAssertPtrEquals(tc, NULL, test_tree->root->data); + CuAssertPtrEquals(tc, NULL, test_tree->root->next); + CuAssertIntEquals(tc, 0, test_tree->root->flavor); + CuAssertIntEquals(tc, 0, test_tree->root->line); + + free(test_tree); +} + diff --git a/kernel/libsepol/cil/test/unit/test_cil_tree.h b/kernel/libsepol/cil/test/unit/test_cil_tree.h new file mode 100644 index 00000000..15c0824a --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_cil_tree.h @@ -0,0 +1,38 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_CIL_TREE_H_ +#define TEST_CIL_TREE_H_ + +#include "CuTest.h" + +void test_cil_tree_node_init(CuTest *); +void test_cil_tree_init(CuTest *); + +#endif diff --git a/kernel/libsepol/cil/test/unit/test_integration.c b/kernel/libsepol/cil/test/unit/test_integration.c new file mode 100644 index 00000000..d9cdb461 --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_integration.c @@ -0,0 +1,76 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#include + +#include "CuTest.h" +#include "test_integration.h" +#include +#include +#include +#include +#include + +void test_integration(CuTest *tc) { + int status = 0, status1 = 0, status2 = 0; + + status = system("./secilc -M -c 24 test/integration.cil &> /dev/null"); + + if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGQUIT)) + printf("Call to system for secilc failed.\n"); + + status1 = system("checkpolicy -M -c 24 -o policy.conf.24 test/policy.conf &> /dev/null"); + + if (WIFSIGNALED(status1) && (WTERMSIG(status1) == SIGINT || WTERMSIG(status1) == SIGQUIT)) + printf("Call to checkpolicy failed.\n"); + + status2 = system("sediff -q policy.24 \\; policy.conf.24 &> /dev/null"); + + if (WIFSIGNALED(status2) && (WTERMSIG(status2) == SIGINT || WTERMSIG(status2) == SIGQUIT)) + printf("Call to sediff for secilc failed.\n"); + + CuAssertIntEquals(tc, 1, WIFEXITED(status)); + CuAssertIntEquals(tc, 0, WEXITSTATUS(status)); + CuAssertIntEquals(tc, 1, WIFEXITED(status1)); + CuAssertIntEquals(tc, 0, WEXITSTATUS(status1)); + CuAssertIntEquals(tc, 1, WIFEXITED(status2)); + CuAssertIntEquals(tc, 0, WEXITSTATUS(status2)); +} + +void test_min_policy(CuTest *tc) { + int status = 0; + + status = system("./secilc -M -c 24 test/policy.cil &> /dev/null"); + + if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGQUIT)) + printf("Call to system for secilc failed.\n"); + + CuAssertIntEquals(tc, 1, WIFEXITED(status)); + CuAssertIntEquals(tc, 0, WEXITSTATUS(status)); +} diff --git a/kernel/libsepol/cil/test/unit/test_integration.h b/kernel/libsepol/cil/test/unit/test_integration.h new file mode 100644 index 00000000..4cbcce3e --- /dev/null +++ b/kernel/libsepol/cil/test/unit/test_integration.h @@ -0,0 +1,38 @@ +/* + * Copyright 2011 Tresys Technology, LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those + * of the authors and should not be interpreted as representing official policies, + * either expressed or implied, of Tresys Technology, LLC. + */ + +#ifndef TEST_INTEGRATION_H +#define TEST_INTEGRATION_H + +#include "CuTest.h" + +void test_min_policy(CuTest *); +void test_integration(CuTest *); + +#endif diff --git a/kernel/libsepol/fuzz/binpolicy-fuzzer.c b/kernel/libsepol/fuzz/binpolicy-fuzzer.c new file mode 100644 index 00000000..462a673b --- /dev/null +++ b/kernel/libsepol/fuzz/binpolicy-fuzzer.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +static int write_binary_policy(policydb_t *p, FILE *outfp) +{ + struct policy_file pf; + + policy_file_init(&pf); + pf.type = PF_USE_STDIO; + pf.fp = outfp; + return ksu_policydb_write(p, &pf); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + policydb_t policydb = {}; + sidtab_t sidtab = {}; + struct policy_file pf; + FILE *devnull = NULL; + + sepol_debug(0); + + policy_file_init(&pf); + pf.type = PF_USE_MEMORY; + pf.data = (char *) data; + pf.len = size; + + if (policydb_init(&policydb)) + goto exit; + + if (ksu_policydb_read(&policydb, &pf, /*verbose=*/0)) + goto exit; + + if (ksu_policydb_load_isids(&policydb, &sidtab)) + goto exit; + + if (policydb.policy_type == POLICY_KERN) + (void) policydb_optimize(&policydb); + + devnull = fopen("/dev/null", "w"); + if (!devnull) + goto exit; + + (void) write_binary_policy(&policydb, devnull); + + (void) sepol_kernel_policydb_to_conf(devnull, &policydb); + + (void) sepol_kernel_policydb_to_cil(devnull, &policydb); + +exit: + if (devnull != NULL) + fclose(devnull); + + ksu_policydb_destroy(&policydb); + sepol_sidtab_destroy(&sidtab); + + /* Non-zero return values are reserved for future use. */ + return 0; +} diff --git a/kernel/libsepol/fuzz/policy.bin b/kernel/libsepol/fuzz/policy.bin new file mode 100644 index 00000000..6f977ef3 Binary files /dev/null and b/kernel/libsepol/fuzz/policy.bin differ diff --git a/kernel/libsepol/fuzz/secilc-fuzzer.c b/kernel/libsepol/fuzz/secilc-fuzzer.c new file mode 100644 index 00000000..9a1a16de --- /dev/null +++ b/kernel/libsepol/fuzz/secilc-fuzzer.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +static void log_handler(__attribute__((unused)) int lvl, __attribute__((unused)) const char *msg) { + /* be quiet */ +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + enum cil_log_level log_level = CIL_ERR; + struct sepol_policy_file *pf = NULL; + FILE *dev_null = NULL; + int target = SEPOL_TARGET_SELINUX; + int disable_dontaudit = 0; + int multiple_decls = 0; + int disable_neverallow = 0; + int preserve_tunables = 0; + int policyvers = POLICYDB_VERSION_MAX; + int mls = -1; + int attrs_expand_generated = 0; + struct cil_db *db = NULL; + sepol_policydb_t *pdb = NULL; + + cil_set_log_level(log_level); + cil_set_log_handler(log_handler); + + cil_db_init(&db); + cil_set_disable_dontaudit(db, disable_dontaudit); + cil_set_multiple_decls(db, multiple_decls); + cil_set_disable_neverallow(db, disable_neverallow); + cil_set_preserve_tunables(db, preserve_tunables); + cil_set_mls(db, mls); + cil_set_target_platform(db, target); + cil_set_policy_version(db, policyvers); + cil_set_attrs_expand_generated(db, attrs_expand_generated); + + if (cil_add_file(db, "fuzz", (const char *)data, size) != SEPOL_OK) + goto exit; + + if (cil_compile(db) != SEPOL_OK) + goto exit; + + if (cil_build_policydb(db, &pdb) != SEPOL_OK) + goto exit; + + if (sepol_policydb_optimize(pdb) != SEPOL_OK) + goto exit; + + dev_null = fopen("/dev/null", "w"); + if (dev_null == NULL) + goto exit; + + if (sepol_policy_file_create(&pf) != 0) + goto exit; + + sepol_policy_file_set_fp(pf, dev_null); + + if (sepol_policydb_write(pdb, pf) != 0) + goto exit; +exit: + if (dev_null != NULL) + fclose(dev_null); + + cil_db_destroy(&db); + sepol_policydb_free(pdb); + sepol_policy_file_free(pf); + return 0; +} diff --git a/kernel/libsepol/include/Makefile b/kernel/libsepol/include/Makefile new file mode 100644 index 00000000..1ad4ecab --- /dev/null +++ b/kernel/libsepol/include/Makefile @@ -0,0 +1,17 @@ +# Installation directories. +PREFIX ?= /usr +INCDIR = $(PREFIX)/include/sepol +CILDIR ?= ../cil + +all: + +install: all + test -d $(DESTDIR)$(INCDIR) || install -m 755 -d $(DESTDIR)$(INCDIR) + test -d $(DESTDIR)$(INCDIR)/policydb || install -m 755 -d $(DESTDIR)$(INCDIR)/policydb + test -d $(DESTDIR)$(INCDIR)/cil || install -m 755 -d $(DESTDIR)$(INCDIR)/cil + install -m 644 $(wildcard sepol/*.h) $(DESTDIR)$(INCDIR) + install -m 644 $(wildcard sepol/policydb/*.h) $(DESTDIR)$(INCDIR)/policydb + install -m 644 $(wildcard $(CILDIR)/include/cil/*.h) $(DESTDIR)$(INCDIR)/cil + +indent: + ../../scripts/Lindent $(wildcard sepol/*.h) diff --git a/kernel/libsepol/include/sepol/boolean_record.h b/kernel/libsepol/include/sepol/boolean_record.h new file mode 100644 index 00000000..09cd01f8 --- /dev/null +++ b/kernel/libsepol/include/sepol/boolean_record.h @@ -0,0 +1,59 @@ +#ifndef _SEPOL_BOOLEAN_RECORD_H_ +#define _SEPOL_BOOLEAN_RECORD_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_bool; +struct sepol_bool_key; +typedef struct sepol_bool sepol_bool_t; +typedef struct sepol_bool_key sepol_bool_key_t; + +/* Key */ +extern int sepol_bool_key_create(sepol_handle_t * handle, + const char *name, sepol_bool_key_t ** key); + +extern void sepol_bool_key_unpack(const sepol_bool_key_t * key, + const char **name); + +extern int sepol_bool_key_extract(sepol_handle_t * handle, + const sepol_bool_t * boolean, + sepol_bool_key_t ** key_ptr); + +extern void sepol_bool_key_free(sepol_bool_key_t * key); + +extern int sepol_bool_compare(const sepol_bool_t * boolean, + const sepol_bool_key_t * key); + +extern int sepol_bool_compare2(const sepol_bool_t * boolean, + const sepol_bool_t * boolean2); + +/* Name */ +extern const char *sepol_bool_get_name(const sepol_bool_t * boolean); + +extern int sepol_bool_set_name(sepol_handle_t * handle, + sepol_bool_t * boolean, const char *name); + +/* Value */ +extern int sepol_bool_get_value(const sepol_bool_t * boolean); + +extern void sepol_bool_set_value(sepol_bool_t * boolean, int value); + +/* Create/Clone/Destroy */ +extern int sepol_bool_create(sepol_handle_t * handle, sepol_bool_t ** bool_ptr); + +extern int sepol_bool_clone(sepol_handle_t * handle, + const sepol_bool_t * boolean, + sepol_bool_t ** bool_ptr); + +extern void sepol_bool_free(sepol_bool_t * boolean); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/booleans.h b/kernel/libsepol/include/sepol/booleans.h new file mode 100644 index 00000000..25229057 --- /dev/null +++ b/kernel/libsepol/include/sepol/booleans.h @@ -0,0 +1,49 @@ +#ifndef _SEPOL_BOOLEANS_H_ +#define _SEPOL_BOOLEANS_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set the specified boolean */ +extern int sepol_bool_set(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_bool_key_t * key, + const sepol_bool_t * data); + +/* Return the number of booleans */ +extern int sepol_bool_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if the specified boolean exists */ +extern int sepol_bool_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_bool_key_t * key, int *response); + +/* Query a boolean - returns the boolean, or NULL if not found */ +extern int sepol_bool_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_bool_key_t * key, + sepol_bool_t ** response); + +/* Iterate the booleans + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_bool_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_bool_t * boolean, + void *fn_arg), void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/context.h b/kernel/libsepol/include/sepol/context.h new file mode 100644 index 00000000..b3e5497d --- /dev/null +++ b/kernel/libsepol/include/sepol/context.h @@ -0,0 +1,34 @@ +#ifndef _SEPOL_CONTEXT_H_ +#define _SEPOL_CONTEXT_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* -- Deprecated -- */ + +extern int sepol_check_context(const char *context); + +/* -- End deprecated -- */ + +extern int sepol_context_check(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_context_t * context); + +extern int sepol_mls_contains(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const char *mls1, + const char *mls2, int *response); + +extern int sepol_mls_check(sepol_handle_t * handle, + const sepol_policydb_t * policydb, const char *mls); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/context_record.h b/kernel/libsepol/include/sepol/context_record.h new file mode 100644 index 00000000..1dcbebb2 --- /dev/null +++ b/kernel/libsepol/include/sepol/context_record.h @@ -0,0 +1,61 @@ +#ifndef _SEPOL_CONTEXT_RECORD_H_ +#define _SEPOL_CONTEXT_RECORD_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_context; +typedef struct sepol_context sepol_context_t; + +/* We don't need a key, because the context is never stored + * in a data collection by itself */ + +/* User */ +extern const char *sepol_context_get_user(const sepol_context_t * con); + +extern int sepol_context_set_user(sepol_handle_t * handle, + sepol_context_t * con, const char *user); + +/* Role */ +extern const char *sepol_context_get_role(const sepol_context_t * con); + +extern int sepol_context_set_role(sepol_handle_t * handle, + sepol_context_t * con, const char *role); + +/* Type */ +extern const char *sepol_context_get_type(const sepol_context_t * con); + +extern int sepol_context_set_type(sepol_handle_t * handle, + sepol_context_t * con, const char *type); + +/* MLS */ +extern const char *sepol_context_get_mls(const sepol_context_t * con); + +extern int sepol_context_set_mls(sepol_handle_t * handle, + sepol_context_t * con, const char *mls_range); + +/* Create/Clone/Destroy */ +extern int sepol_context_create(sepol_handle_t * handle, + sepol_context_t ** con_ptr); + +extern int sepol_context_clone(sepol_handle_t * handle, + const sepol_context_t * con, + sepol_context_t ** con_ptr); + +extern void sepol_context_free(sepol_context_t * con); + +/* Parse to/from string */ +extern int sepol_context_from_string(sepol_handle_t * handle, + const char *str, sepol_context_t ** con); + +extern int sepol_context_to_string(sepol_handle_t * handle, + const sepol_context_t * con, char **str_ptr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/debug.h b/kernel/libsepol/include/sepol/debug.h new file mode 100644 index 00000000..972a4de8 --- /dev/null +++ b/kernel/libsepol/include/sepol/debug.h @@ -0,0 +1,43 @@ +#ifndef _SEPOL_DEBUG_H_ +#define _SEPOL_DEBUG_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Deprecated */ +extern void sepol_debug(int on); +/* End deprecated */ + +#define SEPOL_MSG_ERR 1 +#define SEPOL_MSG_WARN 2 +#define SEPOL_MSG_INFO 3 + +extern int sepol_msg_get_level(sepol_handle_t * handle); + +extern const char *sepol_msg_get_channel(sepol_handle_t * handle); + +extern const char *sepol_msg_get_fname(sepol_handle_t * handle); + +/* Set the messaging callback. + * By the default, the callback will print + * the message on standard output, in a + * particular format. Passing NULL here + * indicates that messaging should be suppressed */ +extern void sepol_msg_set_callback(sepol_handle_t * handle, +#ifdef __GNUC__ + __attribute__ ((format(printf, 3, 4))) +#endif + void (*msg_callback) (void *varg, + sepol_handle_t * + handle, + const char *fmt, ...), + void *msg_callback_arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/errcodes.h b/kernel/libsepol/include/sepol/errcodes.h new file mode 100644 index 00000000..23d4711f --- /dev/null +++ b/kernel/libsepol/include/sepol/errcodes.h @@ -0,0 +1,34 @@ +/* Author: Karl MacMillan */ + +#ifndef __sepol_errno_h__ +#define __sepol_errno_h__ + +// #include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SEPOL_OK 0 + +/* These first error codes are defined for compatibility with + * previous version of libsepol. In the future, custom error + * codes that don't map to system error codes should be defined + * outside of the range of system error codes. + */ +#define SEPOL_ERR -1 +#define SEPOL_ENOTSUP -2 /* feature not supported in module language */ +#define SEPOL_EREQ -3 /* requirements not met */ + +/* Error codes that map to system error codes */ +#define SEPOL_ENOMEM -ENOMEM +#define SEPOL_ERANGE -ERANGE +#define SEPOL_EEXIST -EEXIST +#define SEPOL_ENOENT -ENOENT + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/handle.h b/kernel/libsepol/include/sepol/handle.h new file mode 100644 index 00000000..27cbd6c4 --- /dev/null +++ b/kernel/libsepol/include/sepol/handle.h @@ -0,0 +1,42 @@ +#ifndef _SEPOL_HANDLE_H_ +#define _SEPOL_HANDLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_handle; +typedef struct sepol_handle sepol_handle_t; + +/* Create and return a sepol handle. */ +sepol_handle_t *sepol_handle_create(void); + +/* Get whether or not dontaudits will be disabled, same values as + * specified by set_disable_dontaudit. This value reflects the state + * your system will be set to upon commit, not necessarily its + * current state.*/ +int sepol_get_disable_dontaudit(sepol_handle_t * sh); + +/* Set whether or not to disable dontaudits, 0 is default and does + * not disable dontaudits, 1 disables them */ +void sepol_set_disable_dontaudit(sepol_handle_t * sh, int disable_dontaudit); + +/* Set whether module_expand() should consume the base policy passed in. + * This should reduce the amount of memory required to expand the policy. */ +void sepol_set_expand_consume_base(sepol_handle_t * sh, int consume_base); + +/* Destroy a sepol handle. */ +void sepol_handle_destroy(sepol_handle_t *); + +/* Get whether or not needless unused branch of tunables would be preserved */ +int sepol_get_preserve_tunables(sepol_handle_t * sh); + +/* Set whether or not to preserve the needless unused branch of tunables, + * 0 is default and discard such branch, 1 preserves them */ +void sepol_set_preserve_tunables(sepol_handle_t * sh, int preserve_tunables); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/ibendport_record.h b/kernel/libsepol/include/sepol/ibendport_record.h new file mode 100644 index 00000000..2a37ec63 --- /dev/null +++ b/kernel/libsepol/include/sepol/ibendport_record.h @@ -0,0 +1,72 @@ +#ifndef _SEPOL_IBENDPORT_RECORD_H_ +#define _SEPOL_IBENDPORT_RECORD_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_ibendport; +struct sepol_ibendport_key; +typedef struct sepol_ibendport sepol_ibendport_t; +typedef struct sepol_ibendport_key sepol_ibendport_key_t; + +extern int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, + const sepol_ibendport_key_t *key); + +extern int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, + const sepol_ibendport_t *ibendport2); + +extern int sepol_ibendport_key_create(sepol_handle_t *handle, + const char *ibdev_name, + int port, + sepol_ibendport_key_t **key_ptr); + +extern void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key, + const char **ibdev_name, + int *port); + +extern int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle, + char **ibdev_name); + +extern int sepol_ibendport_key_extract(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_key_t **key_ptr); + +extern void sepol_ibendport_key_free(sepol_ibendport_key_t *key); + +extern void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port); + +extern int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport); + +extern int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + char **ibdev_name); + +extern int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, + const char *ibdev_name); + +extern sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport); + +extern int sepol_ibendport_set_con(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, + sepol_context_t *con); + +extern int sepol_ibendport_create(sepol_handle_t *handle, + sepol_ibendport_t **ibendport_ptr); + +extern int sepol_ibendport_clone(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_t **ibendport_ptr); + +extern void sepol_ibendport_free(sepol_ibendport_t *ibendport); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/ibendports.h b/kernel/libsepol/include/sepol/ibendports.h new file mode 100644 index 00000000..4ad77a12 --- /dev/null +++ b/kernel/libsepol/include/sepol/ibendports.h @@ -0,0 +1,50 @@ +#ifndef _SEPOL_IBENDPORTS_H_ +#define _SEPOL_IBENDPORTS_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return the number of ibendports */ +extern int sepol_ibendport_count(sepol_handle_t *handle, + const sepol_policydb_t *p, + unsigned int *response); + +/* Check if a ibendport exists */ +extern int sepol_ibendport_exists(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibendport_key_t *key, int *response); + +/* Query a ibendport - returns the ibendport, or NULL if not found */ +extern int sepol_ibendport_query(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibendport_key_t *key, + sepol_ibendport_t **response); + +/* Modify a ibendport, or add it, if the key is not found */ +extern int sepol_ibendport_modify(sepol_handle_t *handle, + sepol_policydb_t *policydb, + const sepol_ibendport_key_t *key, + const sepol_ibendport_t *data); + +/* Iterate the ibendports + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue + */ +extern int sepol_ibendport_iterate(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + int (*fn)(const sepol_ibendport_t *ibendport, + void *fn_arg), void *arg); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/ibpkey_record.h b/kernel/libsepol/include/sepol/ibpkey_record.h new file mode 100644 index 00000000..01f6d586 --- /dev/null +++ b/kernel/libsepol/include/sepol/ibpkey_record.h @@ -0,0 +1,80 @@ +#ifndef _SEPOL_IBPKEY_RECORD_H_ +#define _SEPOL_IBPKEY_RECORD_H_ + +// #include +// #include +#include +#include + +#define INET6_ADDRLEN 16 + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_ibpkey; +struct sepol_ibpkey_key; +typedef struct sepol_ibpkey sepol_ibpkey_t; +typedef struct sepol_ibpkey_key sepol_ibpkey_key_t; + +extern int sepol_ibpkey_compare(const sepol_ibpkey_t *ibpkey, + const sepol_ibpkey_key_t *key); + +extern int sepol_ibpkey_compare2(const sepol_ibpkey_t *ibpkey, + const sepol_ibpkey_t *ibpkey2); + +extern int sepol_ibpkey_key_create(sepol_handle_t *handle, + const char *subnet_prefix, + int low, int high, + sepol_ibpkey_key_t **key_ptr); + +extern void sepol_ibpkey_key_unpack(const sepol_ibpkey_key_t *key, + uint64_t *subnet_prefix, + int *low, int *high); + +extern int sepol_ibpkey_key_extract(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + sepol_ibpkey_key_t **key_ptr); + +extern void sepol_ibpkey_key_free(sepol_ibpkey_key_t *key); + +extern int sepol_ibpkey_get_low(const sepol_ibpkey_t *ibpkey); + +extern int sepol_ibpkey_get_high(const sepol_ibpkey_t *ibpkey); + +extern void sepol_ibpkey_set_pkey(sepol_ibpkey_t *ibpkey, int pkey_num); + +extern void sepol_ibpkey_set_range(sepol_ibpkey_t *ibpkey, int low, int high); + +extern int sepol_ibpkey_get_subnet_prefix(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + char **subnet_prefix); + +extern uint64_t sepol_ibpkey_get_subnet_prefix_bytes(const sepol_ibpkey_t *ibpkey); + +extern int sepol_ibpkey_set_subnet_prefix(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, + const char *subnet_prefix); + +extern void sepol_ibpkey_set_subnet_prefix_bytes(sepol_ibpkey_t *ibpkey, + uint64_t subnet_prefix); + +extern sepol_context_t *sepol_ibpkey_get_con(const sepol_ibpkey_t *ibpkey); + +extern int sepol_ibpkey_set_con(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, sepol_context_t *con); + +extern int sepol_ibpkey_create(sepol_handle_t *handle, sepol_ibpkey_t **ibpkey_ptr); + +extern int sepol_ibpkey_clone(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + sepol_ibpkey_t **ibpkey_ptr); + +extern void sepol_ibpkey_free(sepol_ibpkey_t *ibpkey); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/ibpkeys.h b/kernel/libsepol/include/sepol/ibpkeys.h new file mode 100644 index 00000000..4b69d1e9 --- /dev/null +++ b/kernel/libsepol/include/sepol/ibpkeys.h @@ -0,0 +1,50 @@ +#ifndef _SEPOL_IBPKEYS_H_ +#define _SEPOL_IBPKEYS_H_ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return the number of ibpkeys */ +extern int sepol_ibpkey_count(sepol_handle_t *handle, + const sepol_policydb_t *p, unsigned int *response); + +/* Check if a ibpkey exists */ +extern int sepol_ibpkey_exists(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibpkey_key_t *key, int *response); + +/* Query a ibpkey - returns the ibpkey, or NULL if not found */ +extern int sepol_ibpkey_query(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibpkey_key_t *key, + sepol_ibpkey_t **response); + +/* Modify a ibpkey, or add it, if the key is not found */ +extern int sepol_ibpkey_modify(sepol_handle_t *handle, + sepol_policydb_t *policydb, + const sepol_ibpkey_key_t *key, + const sepol_ibpkey_t *data); + +/* Iterate the ibpkeys + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue + */ +extern int sepol_ibpkey_iterate(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + int (*fn)(const sepol_ibpkey_t *ibpkey, + void *fn_arg), void *arg); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/iface_record.h b/kernel/libsepol/include/sepol/iface_record.h new file mode 100644 index 00000000..098bc779 --- /dev/null +++ b/kernel/libsepol/include/sepol/iface_record.h @@ -0,0 +1,67 @@ +#ifndef _SEPOL_IFACE_RECORD_H_ +#define _SEPOL_IFACE_RECORD_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_iface; +struct sepol_iface_key; +typedef struct sepol_iface sepol_iface_t; +typedef struct sepol_iface_key sepol_iface_key_t; + +/* Key */ +extern int sepol_iface_compare(const sepol_iface_t * iface, + const sepol_iface_key_t * key); + +extern int sepol_iface_compare2(const sepol_iface_t * iface, + const sepol_iface_t * iface2); + +extern void sepol_iface_key_unpack(const sepol_iface_key_t * key, + const char **name); + +extern int sepol_iface_key_create(sepol_handle_t * handle, + const char *name, + sepol_iface_key_t ** key_ptr); + +extern int sepol_iface_key_extract(sepol_handle_t * handle, + const sepol_iface_t * iface, + sepol_iface_key_t ** key_ptr); + +extern void sepol_iface_key_free(sepol_iface_key_t * key); + +/* Name */ +extern const char *sepol_iface_get_name(const sepol_iface_t * iface); + +extern int sepol_iface_set_name(sepol_handle_t * handle, + sepol_iface_t * iface, const char *name); + +/* Context */ +extern sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface); + +extern int sepol_iface_set_ifcon(sepol_handle_t * handle, + sepol_iface_t * iface, sepol_context_t * con); + +extern sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface); + +extern int sepol_iface_set_msgcon(sepol_handle_t * handle, + sepol_iface_t * iface, sepol_context_t * con); + +/* Create/Clone/Destroy */ +extern int sepol_iface_create(sepol_handle_t * handle, + sepol_iface_t ** iface_ptr); + +extern int sepol_iface_clone(sepol_handle_t * handle, + const sepol_iface_t * iface, + sepol_iface_t ** iface_ptr); + +extern void sepol_iface_free(sepol_iface_t * iface); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/interfaces.h b/kernel/libsepol/include/sepol/interfaces.h new file mode 100644 index 00000000..7ef23ce3 --- /dev/null +++ b/kernel/libsepol/include/sepol/interfaces.h @@ -0,0 +1,51 @@ +#ifndef __SEPOL_INTERFACES_H_ +#define __SEPOL_INTERFACES_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return the number of interfaces */ +extern int sepol_iface_count(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + unsigned int *response); + +/* Check if an interface exists */ +extern int sepol_iface_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_iface_key_t * key, int *response); + +/* Query an interface - returns the interface, + * or NULL if not found */ +extern int sepol_iface_query(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_iface_key_t * key, + sepol_iface_t ** response); + +/* Modify an interface, or add it, if the key + * is not found */ +extern int sepol_iface_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_iface_key_t * key, + const sepol_iface_t * data); + +/* Iterate the interfaces + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_iface_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_iface_t * iface, + void *fn_arg), void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/kernel_to_cil.h b/kernel/libsepol/include/sepol/kernel_to_cil.h new file mode 100644 index 00000000..f5becb26 --- /dev/null +++ b/kernel/libsepol/include/sepol/kernel_to_cil.h @@ -0,0 +1,5 @@ +// #include + +#include + +int sepol_kernel_policydb_to_cil(FILE *fp, struct policydb *pdb); diff --git a/kernel/libsepol/include/sepol/kernel_to_conf.h b/kernel/libsepol/include/sepol/kernel_to_conf.h new file mode 100644 index 00000000..2313f384 --- /dev/null +++ b/kernel/libsepol/include/sepol/kernel_to_conf.h @@ -0,0 +1,5 @@ +#include + +#include + +int sepol_kernel_policydb_to_conf(FILE *fp, struct policydb *pdb); diff --git a/kernel/libsepol/include/sepol/module.h b/kernel/libsepol/include/sepol/module.h new file mode 100644 index 00000000..2732bd5e --- /dev/null +++ b/kernel/libsepol/include/sepol/module.h @@ -0,0 +1,90 @@ +#ifndef _SEPOL_MODULE_H_ +#define _SEPOL_MODULE_H_ + +// #include +// #include +// #include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_module_package; +typedef struct sepol_module_package sepol_module_package_t; + +/* Module package public interfaces. */ + +extern int sepol_module_package_create(sepol_module_package_t ** p); + +extern void sepol_module_package_free(sepol_module_package_t * p); + +extern char *sepol_module_package_get_file_contexts(sepol_module_package_t * p); + +extern size_t sepol_module_package_get_file_contexts_len(sepol_module_package_t + * p); + +extern int sepol_module_package_set_file_contexts(sepol_module_package_t * p, + char *data, size_t len); + +extern char *sepol_module_package_get_seusers(sepol_module_package_t * p); + +extern size_t sepol_module_package_get_seusers_len(sepol_module_package_t * p); + +extern int sepol_module_package_set_seusers(sepol_module_package_t * p, + char *data, size_t len); + +extern char *sepol_module_package_get_user_extra(sepol_module_package_t * p); + +extern size_t sepol_module_package_get_user_extra_len(sepol_module_package_t * + p); + +extern int sepol_module_package_set_user_extra(sepol_module_package_t * p, + char *data, size_t len); + +extern char *sepol_module_package_get_netfilter_contexts(sepol_module_package_t + * p); + +extern size_t +sepol_module_package_get_netfilter_contexts_len(sepol_module_package_t * p); + +extern int sepol_module_package_set_netfilter_contexts(sepol_module_package_t * + p, char *data, + size_t len); + +extern sepol_policydb_t *sepol_module_package_get_policy(sepol_module_package_t + * p); + +extern int sepol_link_packages(sepol_handle_t * handle, + sepol_module_package_t * base, + sepol_module_package_t ** modules, + int num_modules, int verbose); + +extern int sepol_module_package_read(sepol_module_package_t * mod, + struct sepol_policy_file *file, + int verbose); + +extern int sepol_module_package_info(struct sepol_policy_file *file, + int *type, char **name, char **version); + +extern int sepol_module_package_write(sepol_module_package_t * p, + struct sepol_policy_file *file); + +/* Module linking/expanding public interfaces. */ + +extern int sepol_link_modules(sepol_handle_t * handle, + sepol_policydb_t * base, + sepol_policydb_t ** modules, + size_t len, int verbose); + +extern int sepol_expand_module(sepol_handle_t * handle, + sepol_policydb_t * base, + sepol_policydb_t * out, int verbose, int check); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/module_to_cil.h b/kernel/libsepol/include/sepol/module_to_cil.h new file mode 100644 index 00000000..18bb3bf5 --- /dev/null +++ b/kernel/libsepol/include/sepol/module_to_cil.h @@ -0,0 +1,8 @@ +#include + +#include +#include + +int sepol_module_policydb_to_cil(FILE *fp, struct policydb *pdb, int linked); +int sepol_module_package_to_cil(FILE *fp, struct sepol_module_package *mod_pkg); +int sepol_ppfile_to_module_package(FILE *fp, struct sepol_module_package **mod_pkg); diff --git a/kernel/libsepol/include/sepol/node_record.h b/kernel/libsepol/include/sepol/node_record.h new file mode 100644 index 00000000..38732232 --- /dev/null +++ b/kernel/libsepol/include/sepol/node_record.h @@ -0,0 +1,100 @@ +#ifndef _SEPOL_NODE_RECORD_H_ +#define _SEPOL_NODE_RECORD_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_node; +struct sepol_node_key; +typedef struct sepol_node sepol_node_t; +typedef struct sepol_node_key sepol_node_key_t; + +#define SEPOL_PROTO_IP4 0 +#define SEPOL_PROTO_IP6 1 + +/* Key */ +extern int sepol_node_compare(const sepol_node_t * node, + const sepol_node_key_t * key); + +extern int sepol_node_compare2(const sepol_node_t * node, + const sepol_node_t * node2); + +extern int sepol_node_key_create(sepol_handle_t * handle, + const char *addr, + const char *mask, + int proto, sepol_node_key_t ** key_ptr); + +extern void sepol_node_key_unpack(const sepol_node_key_t * key, + const char **addr, + const char **mask, int *proto); + +extern int sepol_node_key_extract(sepol_handle_t * handle, + const sepol_node_t * node, + sepol_node_key_t ** key_ptr); + +extern void sepol_node_key_free(sepol_node_key_t * key); + +/* Address */ +extern int sepol_node_get_addr(sepol_handle_t * handle, + const sepol_node_t * node, char **addr); + +extern int sepol_node_get_addr_bytes(sepol_handle_t * handle, + const sepol_node_t * node, + char **addr, size_t * addr_sz); + +extern int sepol_node_set_addr(sepol_handle_t * handle, + sepol_node_t * node, + int proto, const char *addr); + +extern int sepol_node_set_addr_bytes(sepol_handle_t * handle, + sepol_node_t * node, + const char *addr, size_t addr_sz); + +/* Netmask */ +extern int sepol_node_get_mask(sepol_handle_t * handle, + const sepol_node_t * node, char **mask); + +extern int sepol_node_get_mask_bytes(sepol_handle_t * handle, + const sepol_node_t * node, + char **mask, size_t * mask_sz); + +extern int sepol_node_set_mask(sepol_handle_t * handle, + sepol_node_t * node, + int proto, const char *mask); + +extern int sepol_node_set_mask_bytes(sepol_handle_t * handle, + sepol_node_t * node, + const char *mask, size_t mask_sz); + +/* Protocol */ +extern int sepol_node_get_proto(const sepol_node_t * node); + +extern void sepol_node_set_proto(sepol_node_t * node, int proto); + +extern const char *sepol_node_get_proto_str(int proto); + +/* Context */ +extern sepol_context_t *sepol_node_get_con(const sepol_node_t * node); + +extern int sepol_node_set_con(sepol_handle_t * handle, + sepol_node_t * node, sepol_context_t * con); + +/* Create/Clone/Destroy */ +extern int sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node_ptr); + +extern int sepol_node_clone(sepol_handle_t * handle, + const sepol_node_t * node, + sepol_node_t ** node_ptr); + +extern void sepol_node_free(sepol_node_t * node); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/nodes.h b/kernel/libsepol/include/sepol/nodes.h new file mode 100644 index 00000000..3cf99d25 --- /dev/null +++ b/kernel/libsepol/include/sepol/nodes.h @@ -0,0 +1,48 @@ +#ifndef _SEPOL_NODES_H_ +#define _SEPOL_NODES_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return the number of nodes */ +extern int sepol_node_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if a node exists */ +extern int sepol_node_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_node_key_t * key, int *response); + +/* Query a node - returns the node, or NULL if not found */ +extern int sepol_node_query(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_node_key_t * key, + sepol_node_t ** response); + +/* Modify a node, or add it, if the key is not found */ +extern int sepol_node_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_node_key_t * key, + const sepol_node_t * data); + +/* Iterate the nodes + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_node_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_node_t * node, + void *fn_arg), void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb.h b/kernel/libsepol/include/sepol/policydb.h new file mode 100644 index 00000000..3e1e685b --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb.h @@ -0,0 +1,160 @@ +#ifndef _SEPOL_POLICYDB_H_ +#define _SEPOL_POLICYDB_H_ + +// #include +#include +// #include +#define FILE void +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_policy_file; +typedef struct sepol_policy_file sepol_policy_file_t; + +struct sepol_policydb; +typedef struct sepol_policydb sepol_policydb_t; + +/* Policy file public interfaces. */ + +/* Create and free memory associated with a policy file. */ +extern int sepol_policy_file_create(sepol_policy_file_t ** pf); +extern void sepol_policy_file_free(sepol_policy_file_t * pf); + +/* + * Set the policy file to represent a binary policy memory image. + * Subsequent operations using the policy file will read and write + * the image located at the specified address with the specified length. + * If 'len' is 0, then merely compute the necessary length upon + * subsequent policydb write operations in order to determine the + * necessary buffer size to allocate. + */ +extern void sepol_policy_file_set_mem(sepol_policy_file_t * pf, + char *data, size_t len); + +/* + * Get the size of the buffer needed to store a policydb write + * previously done on this policy file. + */ +extern int sepol_policy_file_get_len(sepol_policy_file_t * pf, size_t * len); + +/* + * Set the policy file to represent a FILE. + * Subsequent operations using the policy file will read and write + * to the FILE. + */ +extern void sepol_policy_file_set_fp(sepol_policy_file_t * pf, FILE * fp); + +/* + * Associate a handle with a policy file, for use in + * error reporting from subsequent calls that take the + * policy file as an argument. + */ +extern void sepol_policy_file_set_handle(sepol_policy_file_t * pf, + sepol_handle_t * handle); + +/* Policydb public interfaces. */ + +/* Create and free memory associated with a policydb. */ +extern int sepol_policydb_create(sepol_policydb_t ** p); +extern void sepol_policydb_free(sepol_policydb_t * p); + +/* Legal types of policies that the policydb can represent. */ +#define SEPOL_POLICY_KERN 0 +#define SEPOL_POLICY_BASE 1 +#define SEPOL_POLICY_MOD 2 + +/* + * Range of policy versions for the kernel policy type supported + * by this library. + */ +extern int sepol_policy_kern_vers_min(void); +extern int sepol_policy_kern_vers_max(void); + +/* + * Set the policy type as specified, and automatically initialize the + * policy version accordingly to the maximum version supported for the + * policy type. + * Returns -1 if the policy type is not legal. + */ +extern int sepol_policydb_set_typevers(sepol_policydb_t * p, unsigned int type); + +/* + * Set the policy version to a different value. + * Returns -1 if the policy version is not in the supported range for + * the (previously set) policy type. + */ +extern int sepol_policydb_set_vers(sepol_policydb_t * p, unsigned int vers); + +/* Set how to handle unknown class/perms. */ +#define SEPOL_DENY_UNKNOWN 0 +#define SEPOL_REJECT_UNKNOWN 2 +#define SEPOL_ALLOW_UNKNOWN 4 +extern int sepol_policydb_set_handle_unknown(sepol_policydb_t * p, + unsigned int handle_unknown); + +/* Set the target platform */ +#define SEPOL_TARGET_SELINUX 0 +#define SEPOL_TARGET_XEN 1 +extern int sepol_policydb_set_target_platform(sepol_policydb_t * p, + int target_platform); + +/* + * Optimize the policy by removing redundant rules. + */ +extern int sepol_policydb_optimize(sepol_policydb_t * p); + +/* + * Read a policydb from a policy file. + * This automatically sets the type and version based on the + * image contents. + */ +extern int sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf); + +/* + * Write a policydb to a policy file. + * The generated image will be in the binary format corresponding + * to the policy version associated with the policydb. + */ +extern int sepol_policydb_write(sepol_policydb_t * p, sepol_policy_file_t * pf); + +/* + * Extract a policydb from a binary policy memory image. + * This is equivalent to sepol_policydb_read with a policy file + * set to refer to memory. + */ +extern int sepol_policydb_from_image(sepol_handle_t * handle, + void *data, size_t len, + sepol_policydb_t * p); + +/* + * Generate a binary policy memory image from a policydb. + * This is equivalent to sepol_policydb_write with a policy file + * set to refer to memory, but internally handles computing the + * necessary length and allocating an appropriately sized memory + * buffer for the caller. + */ +extern int sepol_policydb_to_image(sepol_handle_t * handle, + sepol_policydb_t * p, + void **newdata, size_t * newlen); + +/* + * Check whether the policydb has MLS enabled. + */ +extern int sepol_policydb_mls_enabled(const sepol_policydb_t * p); + +/* + * Check whether the compatibility mode for SELinux network + * checks should be enabled when using this policy. + */ +extern int sepol_policydb_compat_net(const sepol_policydb_t * p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/avrule_block.h b/kernel/libsepol/include/sepol/policydb/avrule_block.h new file mode 100644 index 00000000..27047d43 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/avrule_block.h @@ -0,0 +1,45 @@ +/* Authors: Jason Tang + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_AVRULE_BLOCK_H_ +#define _SEPOL_AVRULE_BLOCK_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern avrule_block_t *avrule_block_create(void); +extern void avrule_block_destroy(avrule_block_t * x); +extern avrule_decl_t *avrule_decl_create(uint32_t decl_id); +extern void avrule_decl_destroy(avrule_decl_t * x); +extern void avrule_block_list_destroy(avrule_block_t * x); +extern avrule_decl_t *get_avrule_decl(policydb_t * p, uint32_t decl_id); +extern cond_list_t *get_decl_cond_list(policydb_t * p, + avrule_decl_t * decl, + cond_list_t * cond); +extern int is_id_enabled(char *id, policydb_t * p, int symbol_table); +extern int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/avtab.h b/kernel/libsepol/include/sepol/policydb/avtab.h new file mode 100644 index 00000000..bbee92df --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/avtab.h @@ -0,0 +1,153 @@ + +/* Author : Stephen Smalley, */ + +/* + * Updated: Yuichi Nakamura + * Tuned number of hash slots for avtab to reduce memory usage + */ + +/* Updated: Frank Mayer and Karl MacMillan + * + * Added conditional policy language extensions + * + * Copyright (C) 2003 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * An access vector table (avtab) is a hash table + * of access vectors and transition types indexed + * by a type pair and a class. An access vector + * table is used to represent the type enforcement + * tables. + */ + +#ifndef _SEPOL_POLICYDB_AVTAB_H_ +#define _SEPOL_POLICYDB_AVTAB_H_ + +// #include +#include +// #include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct avtab_key { + uint16_t source_type; + uint16_t target_type; + uint16_t target_class; +#define AVTAB_ALLOWED 0x0001 +#define AVTAB_AUDITALLOW 0x0002 +#define AVTAB_AUDITDENY 0x0004 +#define AVTAB_NEVERALLOW 0x0080 +#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) +#define AVTAB_TRANSITION 0x0010 +#define AVTAB_MEMBER 0x0020 +#define AVTAB_CHANGE 0x0040 +#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) +#define AVTAB_XPERMS_ALLOWED 0x0100 +#define AVTAB_XPERMS_AUDITALLOW 0x0200 +#define AVTAB_XPERMS_DONTAUDIT 0x0400 +#define AVTAB_XPERMS_NEVERALLOW 0x0800 +#define AVTAB_XPERMS (AVTAB_XPERMS_ALLOWED | AVTAB_XPERMS_AUDITALLOW | AVTAB_XPERMS_DONTAUDIT) +#define AVTAB_ENABLED_OLD 0x80000000 +#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ + uint16_t specified; /* what fields are specified */ +} avtab_key_t; + +typedef struct avtab_extended_perms { + +#define AVTAB_XPERMS_IOCTLFUNCTION 0x01 +#define AVTAB_XPERMS_IOCTLDRIVER 0x02 + /* extension of the avtab_key specified */ + uint8_t specified; + uint8_t driver; + uint32_t perms[8]; +} avtab_extended_perms_t; + +typedef struct avtab_datum { + uint32_t data; /* access vector or type */ + avtab_extended_perms_t *xperms; +} avtab_datum_t; + +typedef struct avtab_node *avtab_ptr_t; + +struct avtab_node { + avtab_key_t key; + avtab_datum_t datum; + avtab_ptr_t next; + void *parse_context; /* generic context pointer used by parser; + * not saved in binary policy */ + unsigned merged; /* flag for avtab_write only; + not saved in binary policy */ +}; + +typedef struct avtab { + avtab_ptr_t *htable; + uint32_t nel; /* number of elements */ + uint32_t nslot; /* number of hash slots */ + uint32_t mask; /* mask to compute hash func */ +} avtab_t; + +extern int ksu_avtab_init(avtab_t *); +extern int ksu_avtab_alloc(avtab_t *, uint32_t); +extern int avtab_insert(avtab_t * h, avtab_key_t * k, avtab_datum_t * d); + +extern avtab_datum_t *ksu_avtab_search(avtab_t * h, avtab_key_t * k); + +extern void ksu_avtab_destroy(avtab_t * h); + +extern int avtab_map(avtab_t * h, + int (*apply) (avtab_key_t * k, + avtab_datum_t * d, void *args), void *args); + +extern void ksu_avtab_hash_eval(avtab_t * h, char *tag); + +struct policy_file; +extern int ksu_avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a, + int (*insert) (avtab_t * a, avtab_key_t * k, + avtab_datum_t * d, void *p), void *p); + +extern int ksu_avtab_read(avtab_t * a, struct policy_file *fp, uint32_t vers); + +extern avtab_ptr_t ksu_avtab_insert_nonunique(avtab_t * h, avtab_key_t * key, + avtab_datum_t * datum); + +extern avtab_ptr_t avtab_insert_with_parse_context(avtab_t * h, + avtab_key_t * key, + avtab_datum_t * datum, + void *parse_context); + +extern avtab_ptr_t ksu_avtab_search_node(avtab_t * h, avtab_key_t * key); + +extern avtab_ptr_t ksu_avtab_search_node_next(avtab_ptr_t node, int specified); + +#define MAX_AVTAB_HASH_BITS 20 +#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) +#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) +/* avtab_alloc uses one bucket per 2-4 elements, so adjust to get maximum buckets */ +#define MAX_AVTAB_SIZE (MAX_AVTAB_HASH_BUCKETS << 1) + +#ifdef __cplusplus +} +#endif + +#endif /* _AVTAB_H_ */ + +/* FLASK */ diff --git a/kernel/libsepol/include/sepol/policydb/conditional.h b/kernel/libsepol/include/sepol/policydb/conditional.h new file mode 100644 index 00000000..85ba9243 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/conditional.h @@ -0,0 +1,144 @@ +/* Authors: Karl MacMillan + * Frank Mayer + * + * Copyright (C) 2003 - 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_CONDITIONAL_H_ +#define _SEPOL_POLICYDB_CONDITIONAL_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define COND_EXPR_MAXDEPTH 10 + +/* this is the max unique bools in a conditional expression + * for which we precompute all outcomes for the expression. + * + * NOTE - do _NOT_ use value greater than 5 because + * cond_node_t->expr_pre_comp can only hold at most 32 values + */ +#define COND_MAX_BOOLS 5 + +/* + * A conditional expression is a list of operators and operands + * in reverse polish notation. + */ +typedef struct cond_expr { +#define COND_BOOL 1 /* plain bool */ +#define COND_NOT 2 /* !bool */ +#define COND_OR 3 /* bool || bool */ +#define COND_AND 4 /* bool && bool */ +#define COND_XOR 5 /* bool ^ bool */ +#define COND_EQ 6 /* bool == bool */ +#define COND_NEQ 7 /* bool != bool */ +#define COND_LAST COND_NEQ + uint32_t expr_type; + uint32_t bool; + struct cond_expr *next; +} cond_expr_t; + +/* + * Each cond_node_t contains a list of rules to be enabled/disabled + * depending on the current value of the conditional expression. This + * struct is for that list. + */ +typedef struct cond_av_list { + avtab_ptr_t node; + struct cond_av_list *next; +} cond_av_list_t; + +/* + * A cond node represents a conditional block in a policy. It + * contains a conditional expression, the current state of the expression, + * two lists of rules to enable/disable depending on the value of the + * expression (the true list corresponds to if and the false list corresponds + * to else).. + */ +typedef struct cond_node { + int cur_state; + cond_expr_t *expr; + /* these true/false lists point into te_avtab when that is used */ + cond_av_list_t *true_list; + cond_av_list_t *false_list; + /* and these are used during parsing and for modules */ + avrule_t *avtrue_list; + avrule_t *avfalse_list; + /* these fields are not written to binary policy */ + unsigned int nbools; + uint32_t bool_ids[COND_MAX_BOOLS]; + uint32_t expr_pre_comp; + struct cond_node *next; + /* a tunable conditional, calculated and used at expansion */ +#define COND_NODE_FLAGS_TUNABLE UINT32_C(0x01) + uint32_t flags; +} cond_node_t; + +extern int cond_evaluate_expr(policydb_t * p, cond_expr_t * expr); +extern cond_expr_t *cond_copy_expr(cond_expr_t * expr); + +extern int cond_expr_equal(cond_node_t * a, cond_node_t * b); +extern int cond_normalize_expr(policydb_t * p, cond_node_t * cn); +extern void cond_node_destroy(cond_node_t * node); +extern void cond_expr_destroy(cond_expr_t * expr); + +extern cond_node_t *cond_node_find(policydb_t * p, + cond_node_t * needle, cond_node_t * haystack, + int *was_created); + +extern cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node); + +extern cond_node_t *cond_node_search(policydb_t * p, cond_node_t * list, + cond_node_t * cn); + +extern int evaluate_conds(policydb_t * p); + +extern avtab_datum_t *cond_av_list_search(avtab_key_t * key, + cond_av_list_t * cond_list); + +extern void cond_av_list_destroy(cond_av_list_t * list); + +extern void cond_optimize_lists(cond_list_t * cl); + +extern int ksu_cond_policydb_init(policydb_t * p); +extern void ksu_cond_policydb_destroy(policydb_t * p); +extern void cond_list_destroy(cond_list_t * list); + +extern int ksu_cond_init_bool_indexes(policydb_t * p); +extern int ksu_cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p); + +extern int ksu_cond_index_bool(hashtab_key_t key, hashtab_datum_t datum, + void *datap); + +extern int ksu_cond_read_bool(policydb_t * p, hashtab_t h, struct policy_file *fp); + +extern int ksu_cond_read_list(policydb_t * p, cond_list_t ** list, void *fp); + +extern void ksu_cond_compute_av(avtab_t * ctab, avtab_key_t * key, + struct sepol_av_decision *avd); + +#ifdef __cplusplus +} +#endif + +#endif /* _CONDITIONAL_H_ */ diff --git a/kernel/libsepol/include/sepol/policydb/constraint.h b/kernel/libsepol/include/sepol/policydb/constraint.h new file mode 100644 index 00000000..b91fc4e9 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/constraint.h @@ -0,0 +1,84 @@ +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * A constraint is a condition that must be satisfied in + * order for one or more permissions to be granted. + * Constraints are used to impose additional restrictions + * beyond the type-based rules in `te' or the role-based + * transition rules in `rbac'. Constraints are typically + * used to prevent a process from transitioning to a new user + * identity or role unless it is in a privileged type. + * Constraints are likewise typically used to prevent a + * process from labeling an object with a different user + * identity. + */ + +#ifndef _SEPOL_POLICYDB_CONSTRAINT_H_ +#define _SEPOL_POLICYDB_CONSTRAINT_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CEXPR_MAXDEPTH 5 + +struct type_set; + +typedef struct constraint_expr { +#define CEXPR_NOT 1 /* not expr */ +#define CEXPR_AND 2 /* expr and expr */ +#define CEXPR_OR 3 /* expr or expr */ +#define CEXPR_ATTR 4 /* attr op attr */ +#define CEXPR_NAMES 5 /* attr op names */ + uint32_t expr_type; /* expression type */ + +#define CEXPR_USER 1 /* user */ +#define CEXPR_ROLE 2 /* role */ +#define CEXPR_TYPE 4 /* type */ +#define CEXPR_TARGET 8 /* target if set, source otherwise */ +#define CEXPR_XTARGET 16 /* special 3rd target for validatetrans rule */ +#define CEXPR_L1L2 32 /* low level 1 vs. low level 2 */ +#define CEXPR_L1H2 64 /* low level 1 vs. high level 2 */ +#define CEXPR_H1L2 128 /* high level 1 vs. low level 2 */ +#define CEXPR_H1H2 256 /* high level 1 vs. high level 2 */ +#define CEXPR_L1H1 512 /* low level 1 vs. high level 1 */ +#define CEXPR_L2H2 1024 /* low level 2 vs. high level 2 */ + uint32_t attr; /* attribute */ + +#define CEXPR_EQ 1 /* == or eq */ +#define CEXPR_NEQ 2 /* != */ +#define CEXPR_DOM 3 /* dom */ +#define CEXPR_DOMBY 4 /* domby */ +#define CEXPR_INCOMP 5 /* incomp */ + uint32_t op; /* operator */ + + ebitmap_t names; /* names */ + struct type_set *type_names; + + struct constraint_expr *next; /* next expression */ +} constraint_expr_t; + +typedef struct constraint_node { + sepol_access_vector_t permissions; /* constrained permissions */ + constraint_expr_t *expr; /* constraint on permissions */ + struct constraint_node *next; /* next constraint */ +} constraint_node_t; + +struct policydb; + +extern int constraint_expr_init(constraint_expr_t * expr); +extern void constraint_expr_destroy(constraint_expr_t * expr); + +#ifdef __cplusplus +} +#endif + +#endif /* _CONSTRAINT_H_ */ + +/* FLASK */ diff --git a/kernel/libsepol/include/sepol/policydb/context.h b/kernel/libsepol/include/sepol/policydb/context.h new file mode 100644 index 00000000..e72e3832 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/context.h @@ -0,0 +1,149 @@ +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * A security context is a set of security attributes + * associated with each subject and object controlled + * by the security policy. Security contexts are + * externally represented as variable-length strings + * that can be interpreted by a user or application + * with an understanding of the security policy. + * Internally, the security server uses a simple + * structure. This structure is private to the + * security server and can be changed without affecting + * clients of the security server. + */ + +#ifndef _SEPOL_POLICYDB_CONTEXT_H_ +#define _SEPOL_POLICYDB_CONTEXT_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * A security context consists of an authenticated user + * identity, a role, a type and a MLS range. + */ +typedef struct context_struct { + uint32_t user; + uint32_t role; + uint32_t type; + mls_range_t range; +} context_struct_t; + +static inline void mls_context_init(context_struct_t * c) +{ + mls_range_init(&c->range); +} + +static inline int mls_context_cpy(context_struct_t * dst, + const context_struct_t * src) +{ + + if (mls_range_cpy(&dst->range, &src->range) < 0) + return -1; + + return 0; +} + +/* + * Sets both levels in the MLS range of 'dst' to the low level of 'src'. + */ +static inline int mls_context_cpy_low(context_struct_t *dst, const context_struct_t *src) +{ + int rc; + + dst->range.level[0].sens = src->range.level[0].sens; + rc = ksu_ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat); + if (rc) + goto out; + + dst->range.level[1].sens = src->range.level[0].sens; + rc = ksu_ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat); + if (rc) + ksu_ebitmap_destroy(&dst->range.level[0].cat); +out: + return rc; +} + +/* + * Sets both levels in the MLS range of 'dst' to the high level of 'src'. + */ +static inline int mls_context_cpy_high(context_struct_t *dst, const context_struct_t *src) +{ + int rc; + + dst->range.level[0].sens = src->range.level[1].sens; + rc = ksu_ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat); + if (rc) + goto out; + + dst->range.level[1].sens = src->range.level[1].sens; + rc = ksu_ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat); + if (rc) + ksu_ebitmap_destroy(&dst->range.level[0].cat); +out: + return rc; +} + +static inline int mls_context_glblub(context_struct_t *dst, const context_struct_t *c1, const context_struct_t *c2) +{ + return mls_range_glblub(&dst->range, &c1->range, &c2->range); +} + +static inline int mls_context_cmp(const context_struct_t * c1, const context_struct_t * c2) +{ + return (mls_level_eq(&c1->range.level[0], &c2->range.level[0]) && + mls_level_eq(&c1->range.level[1], &c2->range.level[1])); + +} + +static inline void mls_context_destroy(context_struct_t * c) +{ + if (c == NULL) + return; + + mls_range_destroy(&c->range); + mls_context_init(c); +} + +static inline void context_init(context_struct_t * c) +{ + memset(c, 0, sizeof(*c)); +} + +static inline int context_cpy(context_struct_t * dst, const context_struct_t * src) +{ + dst->user = src->user; + dst->role = src->role; + dst->type = src->type; + return mls_context_cpy(dst, src); +} + +static inline void context_destroy(context_struct_t * c) +{ + if (c == NULL) + return; + + c->user = c->role = c->type = 0; + mls_context_destroy(c); +} + +static inline int context_cmp(const context_struct_t * c1, const context_struct_t * c2) +{ + return ((c1->user == c2->user) && + (c1->role == c2->role) && + (c1->type == c2->type) && mls_context_cmp(c1, c2)); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/ebitmap.h b/kernel/libsepol/include/sepol/policydb/ebitmap.h new file mode 100644 index 00000000..f15744a2 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/ebitmap.h @@ -0,0 +1,108 @@ +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * An extensible bitmap is a bitmap that supports an + * arbitrary number of bits. Extensible bitmaps are + * used to represent sets of values, such as types, + * roles, categories, and classes. + * + * Each extensible bitmap is implemented as a linked + * list of bitmap nodes, where each bitmap node has + * an explicitly specified starting bit position within + * the total bitmap. + */ + +#ifndef _SEPOL_POLICYDB_EBITMAP_H_ +#define _SEPOL_POLICYDB_EBITMAP_H_ + +// #include +// #include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAPTYPE uint64_t /* portion of bitmap in each node */ +#define MAPSIZE (sizeof(MAPTYPE) * 8) /* number of bits in node bitmap */ +#define MAPBIT 1ULL /* a bit in the node bitmap */ + +typedef struct ebitmap_node { + uint32_t startbit; /* starting position in the total bitmap */ + MAPTYPE map; /* this node's portion of the bitmap */ + struct ebitmap_node *next; +} ebitmap_node_t; + +typedef struct ebitmap { + ebitmap_node_t *node; /* first node in the bitmap */ + uint32_t highbit; /* highest position in the total bitmap */ +} ebitmap_t; + +#define ebitmap_is_empty(e) (((e)->highbit) == 0) +#define ebitmap_length(e) ((e)->highbit) +#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0) +#define ebitmap_startnode(e) ((e)->node) + +static inline unsigned int ebitmap_start(const ebitmap_t * e, + ebitmap_node_t ** n) +{ + + *n = e->node; + return ebitmap_startbit(e); +} + +static inline void ebitmap_init(ebitmap_t * e) +{ + memset(e, 0, sizeof(*e)); +} + +static inline unsigned int ebitmap_next(ebitmap_node_t ** n, unsigned int bit) +{ + if ((bit == ((*n)->startbit + MAPSIZE - 1)) && (*n)->next) { + *n = (*n)->next; + return (*n)->startbit; + } + + return (bit + 1); +} + +static inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bit) +{ + if (n->map & (MAPBIT << (bit - n->startbit))) + return 1; + return 0; +} + +#define ebitmap_for_each_bit(e, n, bit) \ + for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \ + +#define ebitmap_for_each_positive_bit(e, n, bit) \ + ebitmap_for_each_bit(e, n, bit) if (ebitmap_node_get_bit(n, bit)) \ + +extern int ksu_ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2); +extern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2); +extern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1); +extern int ksu_ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2); +extern int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2); +extern int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit); +extern int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit); +extern unsigned int ebitmap_cardinality(const ebitmap_t *e1); +extern int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2); +extern int ksu_ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src); +extern int ksu_ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2); +extern int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2); +extern int ksu_ebitmap_get_bit(const ebitmap_t * e, unsigned int bit); +extern int ksu_ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value); +extern unsigned int ebitmap_highest_set_bit(const ebitmap_t * e); +extern void ksu_ebitmap_destroy(ebitmap_t * e); +extern int ksu_ebitmap_read(ebitmap_t * e, void *fp); + +#ifdef __cplusplus +} +#endif + +#endif /* _EBITMAP_H_ */ + +/* FLASK */ diff --git a/kernel/libsepol/include/sepol/policydb/expand.h b/kernel/libsepol/include/sepol/policydb/expand.h new file mode 100644 index 00000000..0410d146 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/expand.h @@ -0,0 +1,87 @@ +/* Authors: Jason Tang + * Joshua Brindle + * Karl MacMillan + * + * A set of utility functions that aid policy decision when dealing + * with hierarchal items. + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_EXPAND_H +#define _SEPOL_POLICYDB_EXPAND_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Expand only the avrules for a module. It is valid for this function + * to expand base into itself (i.e. base == out); the typemap for + * this special case should map type[i] to i+1. Likewise the boolmap + * should map bool[i] to i + 1. This function optionally expands + * neverallow rules. If neverallow rules are expanded, there is no + * need to copy them and doing so could cause duplicate entries when + * base == out. If the neverallow rules are not expanded, they are + * just copied to the destination policy so that assertion checking + * can be performed after expand. No assertion or hierarchy checking + * is performed by this function. + */ +extern int expand_module_avrules(sepol_handle_t * handle, policydb_t * base, + policydb_t * out, uint32_t * typemap, uint32_t * boolmap, + uint32_t * rolemap, uint32_t * usermap, + int verbose, int expand_neverallow); +/* + * Expand all parts of a module. Neverallow rules are not expanded (only + * copied). It is not valid to expand base into itself. If check is non-zero, + * performs hierarchy and assertion checking. + */ +extern int expand_module(sepol_handle_t * handle, + policydb_t * base, policydb_t * out, + int verbose, int check); +extern int convert_type_ebitmap(ebitmap_t * src, ebitmap_t * dst, + uint32_t * typemap); +extern int expand_convert_type_set(policydb_t * p, uint32_t * typemap, + type_set_t * set, ebitmap_t * types, + unsigned char alwaysexpand); +extern int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + unsigned char alwaysexpand); +extern int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap); +extern int mls_semantic_level_expand(mls_semantic_level_t *sl, mls_level_t *l, + policydb_t *p, sepol_handle_t *h); +extern int mls_semantic_range_expand(mls_semantic_range_t *sr, mls_range_t *r, + policydb_t *p, sepol_handle_t *h); +extern int expand_rule(sepol_handle_t * handle, + policydb_t * source_pol, + avrule_t * source_rule, avtab_t * dest_avtab, + cond_av_list_t ** cond, cond_av_list_t ** other, + int enabled); + +extern int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa); + +extern int expand_cond_av_list(policydb_t * p, cond_av_list_t * l, + cond_av_list_t ** newl, avtab_t * expa); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/flask_types.h b/kernel/libsepol/include/sepol/policydb/flask_types.h new file mode 100644 index 00000000..8e599d62 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/flask_types.h @@ -0,0 +1,67 @@ +/* -*- linux-c -*- */ + +/* + * Author : Stephen Smalley, + */ + +#ifndef _SEPOL_POLICYDB_FLASK_TYPES_H_ +#define _SEPOL_POLICYDB_FLASK_TYPES_H_ + +/* + * The basic Flask types and constants. + */ + +// #include +#include +// #include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * A security context is a set of security attributes + * associated with each subject and object controlled + * by the security policy. The security context type + * is defined as a variable-length string that can be + * interpreted by any application or user with an + * understanding of the security policy. + */ +typedef char *sepol_security_context_t; +typedef const char *sepol_const_security_context_t; + +/* + * An access vector (AV) is a collection of related permissions + * for a pair of SIDs. The bits within an access vector + * are interpreted differently depending on the class of + * the object. The access vector interpretations are specified + * in policy. + */ +typedef uint32_t sepol_access_vector_t; + +/* + * Each object class is identified by a fixed-size value. + * The set of security classes is specified in policy. + */ +typedef uint16_t sepol_security_class_t; +#define SEPOL_SECCLASS_NULL 0x0000 /* no class */ + +#define SELINUX_MAGIC 0xf97cff8c +#define SELINUX_MOD_MAGIC 0xf97cff8d + +typedef uint32_t sepol_security_id_t; +#define SEPOL_SECSID_NULL 0 + +struct sepol_av_decision { + sepol_access_vector_t allowed; + sepol_access_vector_t decided; + sepol_access_vector_t auditallow; + sepol_access_vector_t auditdeny; + uint32_t seqno; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/hashtab.h b/kernel/libsepol/include/sepol/policydb/hashtab.h new file mode 100644 index 00000000..36b3b5be --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/hashtab.h @@ -0,0 +1,117 @@ +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * A hash table (hashtab) maintains associations between + * key values and datum values. The type of the key values + * and the type of the datum values is arbitrary. The + * functions for hash computation and key comparison are + * provided by the creator of the table. + */ + +#ifndef _SEPOL_POLICYDB_HASHTAB_H_ +#define _SEPOL_POLICYDB_HASHTAB_H_ + +#include + +// #include +// #include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef char *hashtab_key_t; /* generic key type */ +typedef const char *const_hashtab_key_t; /* constant generic key type */ +typedef void *hashtab_datum_t; /* generic datum type */ + +typedef struct hashtab_node *hashtab_ptr_t; + +typedef struct hashtab_node { + hashtab_key_t key; + hashtab_datum_t datum; + hashtab_ptr_t next; +} hashtab_node_t; + +typedef struct hashtab_val { + hashtab_ptr_t *htable; /* hash table */ + unsigned int size; /* number of slots in hash table */ + uint32_t nel; /* number of elements in hash table */ + unsigned int (*hash_value) (struct hashtab_val * h, const_hashtab_key_t key); /* hash function */ + int (*keycmp) (struct hashtab_val * h, const_hashtab_key_t key1, const_hashtab_key_t key2); /* key comparison function */ +} hashtab_val_t; + +typedef hashtab_val_t *hashtab_t; + +/* + Creates a new hash table with the specified characteristics. + + Returns NULL if insufficient space is available or + the new hash table otherwise. + */ +extern hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, + const_hashtab_key_t + key), + int (*keycmp) (hashtab_t h, + const_hashtab_key_t key1, + const_hashtab_key_t key2), + unsigned int size); +/* + Inserts the specified (key, datum) pair into the specified hash table. + + Returns SEPOL_ENOMEM if insufficient space is available or + SEPOL_EEXIST if there is already an entry with the same key or + SEPOL_OK otherwise. + */ +extern int hashtab_insert(hashtab_t h, hashtab_key_t k, hashtab_datum_t d); + +/* + Removes the entry with the specified key from the hash table. + Applies the specified destroy function to (key,datum,args) for + the entry. + + Returns SEPOL_ENOENT if no entry has the specified key or + SEPOL_OK otherwise. + */ +extern int hashtab_remove(hashtab_t h, hashtab_key_t k, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args); + +/* + Searches for the entry with the specified key in the hash table. + + Returns NULL if no entry has the specified key or + the datum of the entry otherwise. + */ +extern hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t k); + +/* + Destroys the specified hash table. + */ +extern void ksu_hashtab_destroy(hashtab_t h); + +/* + Applies the specified apply function to (key,datum,args) + for each entry in the specified hash table. + + The order in which the function is applied to the entries + is dependent upon the internal structure of the hash table. + + If apply returns a non-zero status, then ksu_hashtab_map will cease + iterating through the hash table and will propagate the error + return to its caller. + */ +extern int ksu_hashtab_map(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args); + +extern void hashtab_hash_eval(hashtab_t h, char *tag); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/hierarchy.h b/kernel/libsepol/include/sepol/policydb/hierarchy.h new file mode 100644 index 00000000..eff101fe --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/hierarchy.h @@ -0,0 +1,51 @@ +/* Authors: Jason Tang + * Joshua Brindle + * Karl MacMillan + * + * A set of utility functions that aid policy decision when dealing + * with hierarchal items. + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_HIERARCHY_H_ +#define _SEPOL_POLICYDB_HIERARCHY_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int hierarchy_add_bounds(sepol_handle_t *handle, policydb_t *p); + +extern void bounds_destroy_bad(avtab_ptr_t cur); +extern int bounds_check_type(sepol_handle_t *handle, policydb_t *p, uint32_t child, + uint32_t parent, avtab_ptr_t *bad, int *numbad); + +extern int bounds_check_users(sepol_handle_t *handle, policydb_t *p); +extern int bounds_check_roles(sepol_handle_t *handle, policydb_t *p); +extern int bounds_check_types(sepol_handle_t *handle, policydb_t *p); + +extern int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/link.h b/kernel/libsepol/include/sepol/policydb/link.h new file mode 100644 index 00000000..3ef8f1db --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/link.h @@ -0,0 +1,28 @@ +/* Authors: Jason Tang + * Joshua Brindle + * Karl MacMillan + */ + +#ifndef _SEPOL_POLICYDB_LINK_H +#define _SEPOL_POLICYDB_LINK_H + +#include +#include +#include + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int link_modules(sepol_handle_t * handle, + policydb_t * b, policydb_t ** mods, int len, + int verbose); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/mls_types.h b/kernel/libsepol/include/sepol/policydb/mls_types.h new file mode 100644 index 00000000..aaa0e745 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/mls_types.h @@ -0,0 +1,190 @@ +/* Author : Stephen Smalley, */ +/* + * Updated: Trusted Computer Solutions, Inc. + * + * Support for enhanced MLS infrastructure. + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * Type definitions for the multi-level security (MLS) policy. + */ + +#ifndef _SEPOL_POLICYDB_MLS_TYPES_H_ +#define _SEPOL_POLICYDB_MLS_TYPES_H_ + +// #include +#include +// #include +#define MAX(a,b) a>b?a:b +#define MIN(a,b) a>b?b:a + +// #include +// #include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct mls_level { + uint32_t sens; /* sensitivity */ + ebitmap_t cat; /* category set */ +} mls_level_t; + +typedef struct mls_range { + mls_level_t level[2]; /* low == level[0], high == level[1] */ +} mls_range_t; + +static inline int mls_range_glblub(struct mls_range *dst, const struct mls_range *r1, const struct mls_range *r2) +{ + if (r1->level[1].sens < r2->level[0].sens || r2->level[1].sens < r1->level[0].sens) { + /* These ranges have no common sensitivities */ + return -EINVAL; + } + + /* Take the greatest of the low */ + dst->level[0].sens = MAX(r1->level[0].sens, r2->level[0].sens); + /* Take the least of the high */ + dst->level[1].sens = MIN(r1->level[1].sens, r2->level[1].sens); + + if (ksu_ebitmap_and(&dst->level[0].cat, &r1->level[0].cat, &r2->level[0].cat) < 0) { + return -1; + } + + if (ksu_ebitmap_and(&dst->level[1].cat, &r1->level[1].cat, &r2->level[1].cat) < 0) { + return -1; + } + + return 0; +} + + +static inline int mls_level_cpy(struct mls_level *dst, const struct mls_level *src) +{ + + dst->sens = src->sens; + if (ksu_ebitmap_cpy(&dst->cat, &src->cat) < 0) + return -1; + return 0; +} + +static inline void mls_level_init(struct mls_level *level) +{ + + memset(level, 0, sizeof(mls_level_t)); +} + +static inline void mls_level_destroy(struct mls_level *level) +{ + + if (level == NULL) + return; + + ksu_ebitmap_destroy(&level->cat); + mls_level_init(level); +} + +static inline int mls_level_eq(const struct mls_level *l1, const struct mls_level *l2) +{ + return ((l1->sens == l2->sens) && ksu_ebitmap_cmp(&l1->cat, &l2->cat)); +} + +static inline int mls_level_dom(const struct mls_level *l1, const struct mls_level *l2) +{ + return ((l1->sens >= l2->sens) && ksu_ebitmap_contains(&l1->cat, &l2->cat)); +} + +#define mls_level_incomp(l1, l2) \ +(!mls_level_dom((l1), (l2)) && !mls_level_dom((l2), (l1))) + +#define mls_level_between(l1, l2, l3) \ +(mls_level_dom((l1), (l2)) && mls_level_dom((l3), (l1))) + +#define mls_range_contains(r1, r2) \ +(mls_level_dom(&(r2).level[0], &(r1).level[0]) && \ + mls_level_dom(&(r1).level[1], &(r2).level[1])) + +static inline int mls_range_cpy(mls_range_t * dst, const mls_range_t * src) +{ + + if (mls_level_cpy(&dst->level[0], &src->level[0]) < 0) + goto err; + + if (mls_level_cpy(&dst->level[1], &src->level[1]) < 0) + goto err_destroy; + + return 0; + + err_destroy: + mls_level_destroy(&dst->level[0]); + + err: + return -1; +} + +static inline void mls_range_init(struct mls_range *r) +{ + mls_level_init(&r->level[0]); + mls_level_init(&r->level[1]); +} + +static inline void mls_range_destroy(struct mls_range *r) +{ + mls_level_destroy(&r->level[0]); + mls_level_destroy(&r->level[1]); +} + +static inline int mls_range_eq(const struct mls_range *r1, const struct mls_range *r2) +{ + return (mls_level_eq(&r1->level[0], &r2->level[0]) && + mls_level_eq(&r1->level[1], &r2->level[1])); +} + +typedef struct mls_semantic_cat { + uint32_t low; /* first bit this struct represents */ + uint32_t high; /* last bit represented - equals low for a single cat */ + struct mls_semantic_cat *next; +} mls_semantic_cat_t; + +typedef struct mls_semantic_level { + uint32_t sens; + mls_semantic_cat_t *cat; +} mls_semantic_level_t; + +typedef struct mls_semantic_range { + mls_semantic_level_t level[2]; +} mls_semantic_range_t; + +extern void mls_semantic_cat_init(mls_semantic_cat_t *c); +extern void mls_semantic_cat_destroy(mls_semantic_cat_t *c); +extern void mls_semantic_level_init(mls_semantic_level_t *l); +extern void mls_semantic_level_destroy(mls_semantic_level_t *l); +extern int mls_semantic_level_cpy(mls_semantic_level_t *dst, const mls_semantic_level_t *src); +extern void mls_semantic_range_init(mls_semantic_range_t *r); +extern void mls_semantic_range_destroy(mls_semantic_range_t *r); +extern int mls_semantic_range_cpy(mls_semantic_range_t *dst, const mls_semantic_range_t *src); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/module.h b/kernel/libsepol/include/sepol/policydb/module.h new file mode 100644 index 00000000..e42fda69 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/module.h @@ -0,0 +1,56 @@ +/* Author: Karl MacMillan + * + * Copyright (C) 2004-2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_POLICYDB_MODULE_H_ +#define _SEPOL_POLICYDB_MODULE_H_ + +// #include +// #include + +#include + +#include +#include + +#define SEPOL_MODULE_PACKAGE_MAGIC 0xf97cff8f + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_module_package { + sepol_policydb_t *policy; + uint32_t version; + char *file_contexts; + size_t file_contexts_len; + char *seusers; + size_t seusers_len; + char *user_extra; + size_t user_extra_len; + char *netfilter_contexts; + size_t netfilter_contexts_len; +}; + +extern int sepol_module_package_init(sepol_module_package_t * p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/polcaps.h b/kernel/libsepol/include/sepol/policydb/polcaps.h new file mode 100644 index 00000000..f5e32e60 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/polcaps.h @@ -0,0 +1,32 @@ +#ifndef _SEPOL_POLICYDB_POLCAPS_H_ +#define _SEPOL_POLICYDB_POLCAPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Policy capabilities */ +enum { + POLICYDB_CAP_NETPEER, + POLICYDB_CAP_OPENPERM, + POLICYDB_CAP_EXTSOCKCLASS, + POLICYDB_CAP_ALWAYSNETWORK, + POLICYDB_CAP_CGROUPSECLABEL, + POLICYDB_CAP_NNP_NOSUID_TRANSITION, + POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS, + POLICYDB_CAP_IOCTL_SKIP_CLOEXEC, + __POLICYDB_CAP_MAX +}; +#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) + +/* Convert a capability name to number. */ +extern int sepol_polcap_getnum(const char *name); + +/* Convert a capability number to name. */ +extern const char *sepol_polcap_getname(unsigned int capnum); + +#ifdef __cplusplus +} +#endif + +#endif /* _SEPOL_POLICYDB_POLCAPS_H_ */ diff --git a/kernel/libsepol/include/sepol/policydb/policydb.h b/kernel/libsepol/include/sepol/policydb/policydb.h new file mode 100644 index 00000000..da74304f --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/policydb.h @@ -0,0 +1,828 @@ +/* Author : Stephen Smalley, */ + +/* + * Updated: Joshua Brindle + * Karl MacMillan + * Jason Tang + * + * Module support + * + * Updated: Trusted Computer Solutions, Inc. + * + * Support for enhanced MLS infrastructure. + * + * Updated: Frank Mayer and Karl MacMillan + * + * Added conditional policy language extensions + * + * Updated: Red Hat, Inc. James Morris + * + * Fine-grained netlink support + * IPv6 support + * Code cleanup + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Copyright (C) 2003 - 2004 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Techonolgies Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * A policy database (policydb) specifies the + * configuration data for the security policy. + */ + +#ifndef _SEPOL_POLICYDB_POLICYDB_H_ +#define _SEPOL_POLICYDB_POLICYDB_H_ + +// #include +// #include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define ERRMSG_LEN 1024 + +#define POLICYDB_SUCCESS 0 +#define POLICYDB_ERROR -1 +#define POLICYDB_UNSUPPORTED -2 + +#ifdef __cplusplus +extern "C" { +#endif + +#define IB_DEVICE_NAME_MAX 64 + +/* + * A datum type is defined for each kind of symbol + * in the configuration data: individual permissions, + * common prefixes for access vectors, classes, + * users, roles, types, sensitivities, categories, etc. + */ + +/* type set preserves data needed by modules such as *, ~ and attributes */ +typedef struct type_set { + ebitmap_t types; + ebitmap_t negset; +#define TYPE_STAR 1 +#define TYPE_COMP 2 + uint32_t flags; +} type_set_t; + +typedef struct role_set { + ebitmap_t roles; +#define ROLE_STAR 1 +#define ROLE_COMP 2 + uint32_t flags; +} role_set_t; + +/* Permission attributes */ +typedef struct perm_datum { + symtab_datum_t s; +} perm_datum_t; + +/* Attributes of a common prefix for access vectors */ +typedef struct common_datum { + symtab_datum_t s; + symtab_t permissions; /* common permissions */ +} common_datum_t; + +/* Class attributes */ +typedef struct class_datum { + symtab_datum_t s; + char *comkey; /* common name */ + common_datum_t *comdatum; /* common datum */ + symtab_t permissions; /* class-specific permission symbol table */ + constraint_node_t *constraints; /* constraints on class permissions */ + constraint_node_t *validatetrans; /* special transition rules */ +/* Options how a new object user and role should be decided */ +#define DEFAULT_SOURCE 1 +#define DEFAULT_TARGET 2 + char default_user; + char default_role; + char default_type; +/* Options how a new object range should be decided */ +#define DEFAULT_SOURCE_LOW 1 +#define DEFAULT_SOURCE_HIGH 2 +#define DEFAULT_SOURCE_LOW_HIGH 3 +#define DEFAULT_TARGET_LOW 4 +#define DEFAULT_TARGET_HIGH 5 +#define DEFAULT_TARGET_LOW_HIGH 6 +#define DEFAULT_GLBLUB 7 + char default_range; +} class_datum_t; + +/* Role attributes */ +typedef struct role_datum { + symtab_datum_t s; + ebitmap_t dominates; /* set of roles dominated by this role */ + type_set_t types; /* set of authorized types for role */ + ebitmap_t cache; /* This is an expanded set used for context validation during parsing */ + uint32_t bounds; /* bounds role, if exist */ +#define ROLE_ROLE 0 /* regular role in kernel policies */ +#define ROLE_ATTRIB 1 /* attribute */ + uint32_t flavor; + ebitmap_t roles; /* roles with this attribute */ +} role_datum_t; + +typedef struct role_trans { + uint32_t role; /* current role */ + uint32_t type; /* program executable type, or new object type */ + uint32_t tclass; /* process class, or new object class */ + uint32_t new_role; /* new role */ + struct role_trans *next; +} role_trans_t; + +typedef struct role_allow { + uint32_t role; /* current role */ + uint32_t new_role; /* new role */ + struct role_allow *next; +} role_allow_t; + +/* filename_trans rules */ +typedef struct filename_trans_key { + uint32_t ttype; + uint32_t tclass; + char *name; +} filename_trans_key_t; + +typedef struct filename_trans_datum { + ebitmap_t stypes; + uint32_t otype; + struct filename_trans_datum *next; +} filename_trans_datum_t; + +/* Type attributes */ +typedef struct type_datum { + symtab_datum_t s; + uint32_t primary; /* primary name? can be set to primary value if below is TYPE_ */ +#define TYPE_TYPE 0 /* regular type or alias in kernel policies */ +#define TYPE_ATTRIB 1 /* attribute */ +#define TYPE_ALIAS 2 /* alias in modular policy */ + uint32_t flavor; + ebitmap_t types; /* types with this attribute */ +#define TYPE_FLAGS_PERMISSIVE (1 << 0) +#define TYPE_FLAGS_EXPAND_ATTR_TRUE (1 << 1) +#define TYPE_FLAGS_EXPAND_ATTR_FALSE (1 << 2) +#define TYPE_FLAGS_EXPAND_ATTR (TYPE_FLAGS_EXPAND_ATTR_TRUE | \ + TYPE_FLAGS_EXPAND_ATTR_FALSE) + uint32_t flags; + uint32_t bounds; /* bounds type, if exist */ +} type_datum_t; + +/* + * Properties of type_datum + * available on the policy version >= (MOD_)POLICYDB_VERSION_BOUNDARY + */ +#define TYPEDATUM_PROPERTY_PRIMARY 0x0001 +#define TYPEDATUM_PROPERTY_ATTRIBUTE 0x0002 +#define TYPEDATUM_PROPERTY_ALIAS 0x0004 /* userspace only */ +#define TYPEDATUM_PROPERTY_PERMISSIVE 0x0008 /* userspace only */ + +/* User attributes */ +typedef struct user_datum { + symtab_datum_t s; + role_set_t roles; /* set of authorized roles for user */ + mls_semantic_range_t range; /* MLS range (min. - max.) for user */ + mls_semantic_level_t dfltlevel; /* default login MLS level for user */ + ebitmap_t cache; /* This is an expanded set used for context validation during parsing */ + mls_range_t exp_range; /* expanded range used for validation */ + mls_level_t exp_dfltlevel; /* expanded range used for validation */ + uint32_t bounds; /* bounds user, if exist */ +} user_datum_t; + +/* Sensitivity attributes */ +typedef struct level_datum { + mls_level_t *level; /* sensitivity and associated categories */ + unsigned char isalias; /* is this sensitivity an alias for another? */ + unsigned char defined; +} level_datum_t; + +/* Category attributes */ +typedef struct cat_datum { + symtab_datum_t s; + unsigned char isalias; /* is this category an alias for another? */ +} cat_datum_t; + +typedef struct range_trans { + uint32_t source_type; + uint32_t target_type; + uint32_t target_class; +} range_trans_t; + +/* Boolean data type */ +typedef struct cond_bool_datum { + symtab_datum_t s; + int state; +#define COND_BOOL_FLAGS_TUNABLE 0x01 /* is this a tunable? */ + uint32_t flags; +} cond_bool_datum_t; + +struct cond_node; + +typedef struct cond_node cond_list_t; +struct cond_av_list; + +typedef struct class_perm_node { + uint32_t tclass; + uint32_t data; /* permissions or new type */ + struct class_perm_node *next; +} class_perm_node_t; + +#define UINT32_C(value) (value##UL) + +#define xperm_test(x, p) (UINT32_C(1) & (p[x >> 5] >> (x & 0x1f))) +#define xperm_set(x, p) (p[x >> 5] |= (UINT32_C(1) << (x & 0x1f))) +#define xperm_clear(x, p) (p[x >> 5] &= ~(UINT32_C(1) << (x & 0x1f))) +#define EXTENDED_PERMS_LEN 8 + +typedef struct av_extended_perms { +#define AVRULE_XPERMS_IOCTLFUNCTION 0x01 +#define AVRULE_XPERMS_IOCTLDRIVER 0x02 + uint8_t specified; + uint8_t driver; + /* 256 bits of permissions */ + uint32_t perms[EXTENDED_PERMS_LEN]; +} av_extended_perms_t; + +typedef struct avrule { +/* these typedefs are almost exactly the same as those in avtab.h - they are + * here because of the need to include neverallow and dontaudit messages */ +#define AVRULE_ALLOWED AVTAB_ALLOWED +#define AVRULE_AUDITALLOW AVTAB_AUDITALLOW +#define AVRULE_AUDITDENY AVTAB_AUDITDENY +#define AVRULE_DONTAUDIT 0x0008 +#define AVRULE_NEVERALLOW AVTAB_NEVERALLOW +#define AVRULE_AV (AVRULE_ALLOWED | AVRULE_AUDITALLOW | AVRULE_AUDITDENY | AVRULE_DONTAUDIT | AVRULE_NEVERALLOW) +#define AVRULE_TRANSITION AVTAB_TRANSITION +#define AVRULE_MEMBER AVTAB_MEMBER +#define AVRULE_CHANGE AVTAB_CHANGE +#define AVRULE_TYPE (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE) +#define AVRULE_XPERMS_ALLOWED AVTAB_XPERMS_ALLOWED +#define AVRULE_XPERMS_AUDITALLOW AVTAB_XPERMS_AUDITALLOW +#define AVRULE_XPERMS_DONTAUDIT AVTAB_XPERMS_DONTAUDIT +#define AVRULE_XPERMS_NEVERALLOW AVTAB_XPERMS_NEVERALLOW +#define AVRULE_XPERMS (AVRULE_XPERMS_ALLOWED | AVRULE_XPERMS_AUDITALLOW | \ + AVRULE_XPERMS_DONTAUDIT | AVRULE_XPERMS_NEVERALLOW) + uint32_t specified; +#define RULE_SELF 1 + uint32_t flags; + type_set_t stypes; + type_set_t ttypes; + class_perm_node_t *perms; + av_extended_perms_t *xperms; + unsigned long line; /* line number from policy.conf where + * this rule originated */ + /* source file name and line number (e.g. .te file) */ + char *source_filename; + unsigned long source_line; + struct avrule *next; +} avrule_t; + +typedef struct role_trans_rule { + role_set_t roles; /* current role */ + type_set_t types; /* program executable type, or new object type */ + ebitmap_t classes; /* process class, or new object class */ + uint32_t new_role; /* new role */ + struct role_trans_rule *next; +} role_trans_rule_t; + +typedef struct role_allow_rule { + role_set_t roles; /* current role */ + role_set_t new_roles; /* new roles */ + struct role_allow_rule *next; +} role_allow_rule_t; + +typedef struct filename_trans_rule { + uint32_t flags; /* may have RULE_SELF set */ + type_set_t stypes; + type_set_t ttypes; + uint32_t tclass; + char *name; + uint32_t otype; /* new type */ + struct filename_trans_rule *next; +} filename_trans_rule_t; + +typedef struct range_trans_rule { + type_set_t stypes; + type_set_t ttypes; + ebitmap_t tclasses; + mls_semantic_range_t trange; + struct range_trans_rule *next; +} range_trans_rule_t; + +/* + * The configuration data includes security contexts for + * initial SIDs, unlabeled file systems, TCP and UDP port numbers, + * network interfaces, and nodes. This structure stores the + * relevant data for one such entry. Entries of the same kind + * (e.g. all initial SIDs) are linked together into a list. + */ +typedef struct ocontext { + union { + char *name; /* name of initial SID, fs, netif, fstype, path */ + struct { + uint8_t protocol; + uint16_t low_port; + uint16_t high_port; + } port; /* TCP or UDP port information */ + struct { + uint32_t addr; /* network order */ + uint32_t mask; /* network order */ + } node; /* node information */ + struct { + uint32_t addr[4]; /* network order */ + uint32_t mask[4]; /* network order */ + } node6; /* IPv6 node information */ + uint32_t device; + uint16_t pirq; + struct { + uint64_t low_iomem; + uint64_t high_iomem; + } iomem; + struct { + uint32_t low_ioport; + uint32_t high_ioport; + } ioport; + struct { + uint64_t subnet_prefix; + uint16_t low_pkey; + uint16_t high_pkey; + } ibpkey; + struct { + char *dev_name; + uint8_t port; + } ibendport; + } u; + union { + uint32_t sclass; /* security class for genfs */ + uint32_t behavior; /* labeling behavior for fs_use */ + } v; + context_struct_t context[2]; /* security context(s) */ + sepol_security_id_t sid[2]; /* SID(s) */ + struct ocontext *next; +} ocontext_t; + +typedef struct genfs { + char *fstype; + struct ocontext *head; + struct genfs *next; +} genfs_t; + +/* symbol table array indices */ +#define SYM_COMMONS 0 +#define SYM_CLASSES 1 +#define SYM_ROLES 2 +#define SYM_TYPES 3 +#define SYM_USERS 4 +#define SYM_BOOLS 5 +#define SYM_LEVELS 6 +#define SYM_CATS 7 +#define SYM_NUM 8 + +/* object context array indices */ +#define OCON_ISID 0 /* initial SIDs */ +#define OCON_FS 1 /* unlabeled file systems */ +#define OCON_PORT 2 /* TCP and UDP port numbers */ +#define OCON_NETIF 3 /* network interfaces */ +#define OCON_NODE 4 /* nodes */ +#define OCON_FSUSE 5 /* fs_use */ +#define OCON_NODE6 6 /* IPv6 nodes */ +#define OCON_IBPKEY 7 /* Infiniband PKEY */ +#define OCON_IBENDPORT 8 /* Infiniband End Port */ + +/* object context array indices for Xen */ +#define OCON_XEN_ISID 0 /* initial SIDs */ +#define OCON_XEN_PIRQ 1 /* physical irqs */ +#define OCON_XEN_IOPORT 2 /* io ports */ +#define OCON_XEN_IOMEM 3 /* io memory */ +#define OCON_XEN_PCIDEVICE 4 /* pci devices */ +#define OCON_XEN_DEVICETREE 5 /* device tree node */ + +/* OCON_NUM needs to be the largest index in any platform's ocontext array */ +#define OCON_NUM 9 + +/* section: module information */ + +/* scope_index_t holds all of the symbols that are in scope in a + * particular situation. The bitmaps are indices (and thus must + * subtract one) into the global policydb->scope array. */ +typedef struct scope_index { + ebitmap_t scope[SYM_NUM]; +#define p_classes_scope scope[SYM_CLASSES] +#define p_roles_scope scope[SYM_ROLES] +#define p_types_scope scope[SYM_TYPES] +#define p_users_scope scope[SYM_USERS] +#define p_bools_scope scope[SYM_BOOLS] +#define p_sens_scope scope[SYM_LEVELS] +#define p_cat_scope scope[SYM_CATS] + + /* this array maps from class->value to the permissions within + * scope. if bit (perm->value - 1) is set in map + * class_perms_map[class->value - 1] then that permission is + * enabled for this class within this decl. */ + ebitmap_t *class_perms_map; + /* total number of classes in class_perms_map array */ + uint32_t class_perms_len; +} scope_index_t; + +/* a list of declarations for a particular avrule_decl */ + +/* These two structs declare a block of policy that has TE and RBAC + * statements and declarations. The root block (the global policy) + * can never have an ELSE branch. */ +typedef struct avrule_decl { + uint32_t decl_id; + uint32_t enabled; /* whether this block is enabled */ + + cond_list_t *cond_list; + avrule_t *avrules; + role_trans_rule_t *role_tr_rules; + role_allow_rule_t *role_allow_rules; + range_trans_rule_t *range_tr_rules; + scope_index_t required; /* symbols needed to activate this block */ + scope_index_t declared; /* symbols declared within this block */ + + /* type transition rules with a 'name' component */ + filename_trans_rule_t *filename_trans_rules; + + /* for additive statements (type attribute, roles, and users) */ + symtab_t symtab[SYM_NUM]; + + /* In a linked module this will contain the name of the module + * from which this avrule_decl originated. */ + char *module_name; + + struct avrule_decl *next; +} avrule_decl_t; + +typedef struct avrule_block { + avrule_decl_t *branch_list; + avrule_decl_t *enabled; /* pointer to which branch is enabled. this is + used in linking and never written to disk */ +#define AVRULE_OPTIONAL 1 + uint32_t flags; /* any flags for this block, currently just optional */ + struct avrule_block *next; +} avrule_block_t; + +/* Every identifier has its own scope datum. The datum describes if + * the item is to be included into the final policy during + * expansion. */ +typedef struct scope_datum { +/* Required for this decl */ +#define SCOPE_REQ 1 +/* Declared in this decl */ +#define SCOPE_DECL 2 + uint32_t scope; + uint32_t *decl_ids; + uint32_t decl_ids_len; + /* decl_ids is a list of avrule_decl's that declare/require + * this symbol. If scope==SCOPE_DECL then this is a list of + * declarations. If the symbol may only be declared once + * (types, bools) then decl_ids_len will be exactly 1. For + * implicitly declared things (roles, users) then decl_ids_len + * will be at least 1. */ +} scope_datum_t; + +/* The policy database */ +typedef struct policydb { +#define POLICY_KERN SEPOL_POLICY_KERN +#define POLICY_BASE SEPOL_POLICY_BASE +#define POLICY_MOD SEPOL_POLICY_MOD + uint32_t policy_type; + char *name; + char *version; + int target_platform; + + /* Set when the policydb is modified such that writing is unsupported */ + int unsupported_format; + + /* Whether this policydb is mls, should always be set */ + int mls; + + /* symbol tables */ + symtab_t symtab[SYM_NUM]; +#define p_commons symtab[SYM_COMMONS] +#define p_classes symtab[SYM_CLASSES] +#define p_roles symtab[SYM_ROLES] +#define p_types symtab[SYM_TYPES] +#define p_users symtab[SYM_USERS] +#define p_bools symtab[SYM_BOOLS] +#define p_levels symtab[SYM_LEVELS] +#define p_cats symtab[SYM_CATS] + + /* symbol names indexed by (value - 1) */ + char **sym_val_to_name[SYM_NUM]; +#define p_common_val_to_name sym_val_to_name[SYM_COMMONS] +#define p_class_val_to_name sym_val_to_name[SYM_CLASSES] +#define p_role_val_to_name sym_val_to_name[SYM_ROLES] +#define p_type_val_to_name sym_val_to_name[SYM_TYPES] +#define p_user_val_to_name sym_val_to_name[SYM_USERS] +#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS] +#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS] +#define p_cat_val_to_name sym_val_to_name[SYM_CATS] + + /* class, role, and user attributes indexed by (value - 1) */ + class_datum_t **class_val_to_struct; + role_datum_t **role_val_to_struct; + user_datum_t **user_val_to_struct; + type_datum_t **type_val_to_struct; + + /* module stuff section -- used in parsing and for modules */ + + /* keep track of the scope for every identifier. these are + * hash tables, where the key is the identifier name and value + * a scope_datum_t. as a convenience, one may use the + * p_*_macros (cf. struct scope_index_t declaration). */ + symtab_t scope[SYM_NUM]; + + /* module rule storage */ + avrule_block_t *global; + /* avrule_decl index used for link/expand */ + avrule_decl_t **decl_val_to_struct; + + /* compiled storage of rules - use for the kernel policy */ + + /* type enforcement access vectors and transitions */ + avtab_t te_avtab; + + /* bools indexed by (value - 1) */ + cond_bool_datum_t **bool_val_to_struct; + /* type enforcement conditional access vectors and transitions */ + avtab_t te_cond_avtab; + /* linked list indexing te_cond_avtab by conditional */ + cond_list_t *cond_list; + + /* role transitions */ + role_trans_t *role_tr; + + /* role allows */ + role_allow_t *role_allow; + + /* security contexts of initial SIDs, unlabeled file systems, + TCP or UDP port numbers, network interfaces and nodes */ + ocontext_t *ocontexts[OCON_NUM]; + + /* security contexts for files in filesystems that cannot support + a persistent label mapping or use another + fixed labeling behavior. */ + genfs_t *genfs; + + /* range transitions table (range_trans_key -> mls_range) */ + hashtab_t range_tr; + + /* file transitions with the last path component */ + hashtab_t filename_trans; + uint32_t filename_trans_count; + + ebitmap_t *type_attr_map; + + ebitmap_t *attr_type_map; /* not saved in the binary policy */ + + ebitmap_t policycaps; + + /* this bitmap is referenced by type NOT the typical type-1 used in other + bitmaps. Someday the 0 bit may be used for global permissive */ + ebitmap_t permissive_map; + + unsigned policyvers; + + unsigned handle_unknown; + + sepol_security_class_t process_class; + sepol_security_class_t dir_class; + sepol_access_vector_t process_trans; + sepol_access_vector_t process_trans_dyntrans; +} policydb_t; + +struct sepol_policydb { + struct policydb p; +}; + +extern int policydb_init(policydb_t * p); + +extern int policydb_from_image(sepol_handle_t * handle, + void *data, size_t len, policydb_t * policydb); + +extern int policydb_to_image(sepol_handle_t * handle, + policydb_t * policydb, void **newdata, + size_t * newlen); + +extern int policydb_index_classes(policydb_t * p); + +extern int policydb_index_bools(policydb_t * p); + +extern int policydb_index_others(sepol_handle_t * handle, policydb_t * p, + unsigned int verbose); + +extern int policydb_role_cache(hashtab_key_t key, + hashtab_datum_t datum, + void *arg); + +extern int policydb_user_cache(hashtab_key_t key, + hashtab_datum_t datum, + void *arg); + +extern int policydb_reindex_users(policydb_t * p); + +extern int policydb_optimize(policydb_t * p); + +extern void ksu_policydb_destroy(policydb_t * p); + +extern int ksu_policydb_load_isids(policydb_t * p, sidtab_t * s); + +extern int policydb_sort_ocontexts(policydb_t *p); + +extern int policydb_filetrans_insert(policydb_t *p, uint32_t stype, + uint32_t ttype, uint32_t tclass, + const char *name, char **name_alloc, + uint32_t otype, uint32_t *present_otype); + +/* Deprecated */ +extern int ksu_policydb_context_isvalid(const policydb_t * p, + const context_struct_t * c); + +extern void symtabs_destroy(symtab_t * symtab); +extern int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p); + +extern void class_perm_node_init(class_perm_node_t * x); +extern void type_set_init(type_set_t * x); +extern void type_set_destroy(type_set_t * x); +extern int type_set_cpy(type_set_t * dst, const type_set_t * src); +extern int type_set_or_eq(type_set_t * dst, const type_set_t * other); +extern void role_set_init(role_set_t * x); +extern void role_set_destroy(role_set_t * x); +extern void avrule_init(avrule_t * x); +extern void avrule_destroy(avrule_t * x); +extern void avrule_list_destroy(avrule_t * x); +extern void role_trans_rule_init(role_trans_rule_t * x); +extern void role_trans_rule_list_destroy(role_trans_rule_t * x); +extern void filename_trans_rule_init(filename_trans_rule_t * x); +extern void filename_trans_rule_list_destroy(filename_trans_rule_t * x); + +extern void role_datum_init(role_datum_t * x); +extern void role_datum_destroy(role_datum_t * x); +extern void role_allow_rule_init(role_allow_rule_t * x); +extern void role_allow_rule_destroy(role_allow_rule_t * x); +extern void role_allow_rule_list_destroy(role_allow_rule_t * x); +extern void range_trans_rule_init(range_trans_rule_t *x); +extern void range_trans_rule_destroy(range_trans_rule_t *x); +extern void range_trans_rule_list_destroy(range_trans_rule_t *x); +extern void type_datum_init(type_datum_t * x); +extern void type_datum_destroy(type_datum_t * x); +extern void user_datum_init(user_datum_t * x); +extern void user_datum_destroy(user_datum_t * x); +extern void level_datum_init(level_datum_t * x); +extern void level_datum_destroy(level_datum_t * x); +extern void cat_datum_init(cat_datum_t * x); +extern void cat_datum_destroy(cat_datum_t * x); +extern int check_assertion(policydb_t *p, avrule_t *avrule); +extern int check_assertions(sepol_handle_t * handle, + policydb_t * p, avrule_t * avrules); + +extern int ksu_symtab_insert(policydb_t * x, uint32_t sym, + hashtab_key_t key, hashtab_datum_t datum, + uint32_t scope, uint32_t avrule_decl_id, + uint32_t * value); + +/* A policy "file" may be a memory region referenced by a (data, len) pair + or a file referenced by a FILE pointer. */ +typedef struct policy_file { +#define PF_USE_MEMORY 0 +#define PF_USE_STDIO 1 +#define PF_LEN 2 /* total up length in len field */ + unsigned type; + char *data; + size_t len; + size_t size; + FILE *fp; + struct sepol_handle *handle; +} policy_file_t; + +struct sepol_policy_file { + struct policy_file pf; +}; + +extern void policy_file_init(policy_file_t * x); + +extern int ksu_policydb_read(policydb_t * p, struct policy_file *fp, + unsigned int verbose); +extern int avrule_read_list(policydb_t * p, avrule_t ** avrules, + struct policy_file *fp); + +extern int ksu_policydb_write(struct policydb *p, struct policy_file *pf); +extern int policydb_set_target_platform(policydb_t *p, int platform); + +#define PERM_SYMTAB_SIZE 32 + +/* Identify specific policy version changes */ +#define POLICYDB_VERSION_BASE 15 +#define POLICYDB_VERSION_BOOL 16 +#define POLICYDB_VERSION_IPV6 17 +#define POLICYDB_VERSION_NLCLASS 18 +#define POLICYDB_VERSION_VALIDATETRANS 19 +#define POLICYDB_VERSION_MLS 19 +#define POLICYDB_VERSION_AVTAB 20 +#define POLICYDB_VERSION_RANGETRANS 21 +#define POLICYDB_VERSION_POLCAP 22 +#define POLICYDB_VERSION_PERMISSIVE 23 +#define POLICYDB_VERSION_BOUNDARY 24 +#define POLICYDB_VERSION_FILENAME_TRANS 25 +#define POLICYDB_VERSION_ROLETRANS 26 +#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 +#define POLICYDB_VERSION_DEFAULT_TYPE 28 +#define POLICYDB_VERSION_CONSTRAINT_NAMES 29 +#define POLICYDB_VERSION_XEN_DEVICETREE 30 /* Xen-specific */ +#define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Linux-specific */ +#define POLICYDB_VERSION_INFINIBAND 31 /* Linux-specific */ +#define POLICYDB_VERSION_GLBLUB 32 +#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ + +/* Range of policy versions we understand*/ +#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS + +/* Module versions and specific changes*/ +#define MOD_POLICYDB_VERSION_BASE 4 +#define MOD_POLICYDB_VERSION_VALIDATETRANS 5 +#define MOD_POLICYDB_VERSION_MLS 5 +#define MOD_POLICYDB_VERSION_RANGETRANS 6 +#define MOD_POLICYDB_VERSION_MLS_USERS 6 +#define MOD_POLICYDB_VERSION_POLCAP 7 +#define MOD_POLICYDB_VERSION_PERMISSIVE 8 +#define MOD_POLICYDB_VERSION_BOUNDARY 9 +#define MOD_POLICYDB_VERSION_BOUNDARY_ALIAS 10 +#define MOD_POLICYDB_VERSION_FILENAME_TRANS 11 +#define MOD_POLICYDB_VERSION_ROLETRANS 12 +#define MOD_POLICYDB_VERSION_ROLEATTRIB 13 +#define MOD_POLICYDB_VERSION_TUNABLE_SEP 14 +#define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 15 +#define MOD_POLICYDB_VERSION_DEFAULT_TYPE 16 +#define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES 17 +#define MOD_POLICYDB_VERSION_XPERMS_IOCTL 18 +#define MOD_POLICYDB_VERSION_INFINIBAND 19 +#define MOD_POLICYDB_VERSION_GLBLUB 20 +#define MOD_POLICYDB_VERSION_SELF_TYPETRANS 21 + +#define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_SELF_TYPETRANS + +#define POLICYDB_CONFIG_MLS 1 + +/* macros to check policy feature */ + +/* TODO: add other features here */ + +#define policydb_has_boundary_feature(p) \ + (((p)->policy_type == POLICY_KERN \ + && p->policyvers >= POLICYDB_VERSION_BOUNDARY) || \ + ((p)->policy_type != POLICY_KERN \ + && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY)) + +/* the config flags related to unknown classes/perms are bits 2 and 3 */ +#define DENY_UNKNOWN SEPOL_DENY_UNKNOWN +#define REJECT_UNKNOWN SEPOL_REJECT_UNKNOWN +#define ALLOW_UNKNOWN SEPOL_ALLOW_UNKNOWN + +#define POLICYDB_CONFIG_UNKNOWN_MASK (DENY_UNKNOWN | REJECT_UNKNOWN | ALLOW_UNKNOWN) + +#define OBJECT_R "object_r" +#define OBJECT_R_VAL 1 + +#define POLICYDB_MAGIC SELINUX_MAGIC +#define POLICYDB_STRING "SE Linux" +#define POLICYDB_XEN_STRING "XenFlask" +#define POLICYDB_STRING_MAX_LENGTH 32 +#define POLICYDB_MOD_MAGIC SELINUX_MOD_MAGIC +#define POLICYDB_MOD_STRING "SE Linux Module" + +#ifdef __cplusplus +} +#endif + +#endif /* _POLICYDB_H_ */ + +/* FLASK */ diff --git a/kernel/libsepol/include/sepol/policydb/services.h b/kernel/libsepol/include/sepol/policydb/services.h new file mode 100644 index 00000000..bcb0930f --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/services.h @@ -0,0 +1,258 @@ + +/* -*- linux-c -*- */ + +/* + * Author : Stephen Smalley, + */ + +#ifndef _SEPOL_POLICYDB_SERVICES_H_ +#define _SEPOL_POLICYDB_SERVICES_H_ + +/* + * Security server interface. + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set the policydb and sidtab structures to be used by + the service functions. If not set, then these default + to private structures within libsepol that can only be + initialized and accessed via the service functions themselves. + Setting the structures explicitly allows a program to directly + manipulate them, e.g. checkpolicy populates the structures directly + from a source policy rather than from a binary policy. */ +extern int sepol_set_policydb(policydb_t * p); +extern int sepol_set_sidtab(sidtab_t * s); + +/* Load the security policy. This initializes the policydb + and sidtab based on the provided binary policy. */ +extern int sepol_load_policy(void *data, size_t len); + +/* + * Compute access vectors based on a SID pair for + * the permissions in a particular class. + */ +extern int sepol_compute_av(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_access_vector_t requested, /* IN */ + struct sepol_av_decision *avd); /* OUT */ + +/* Same as above, but also return the reason(s) for any + denials of the requested permissions. */ +#define SEPOL_COMPUTEAV_TE 0x1U +#define SEPOL_COMPUTEAV_CONS 0x2U +#define SEPOL_COMPUTEAV_RBAC 0x4U +#define SEPOL_COMPUTEAV_BOUNDS 0x8U +extern int sepol_compute_av_reason(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason); + +/* + * Same as above, but also returns the constraint expression calculations + * whether allowed or denied in a buffer. This buffer is allocated by + * this call and must be free'd by the caller using free(3). The constraint + * buffer will contain any constraints in infix notation. + * If the SHOW_GRANTED flag is set it will show granted and denied + * constraints. The default is to show only denied constraints. + */ +#define SHOW_GRANTED 1 +extern int sepol_compute_av_reason_buffer(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason, + char **reason_buf, + unsigned int flags); + +/* + * Returns the mls/validatetrans constraint expression calculations in + * a buffer that must be free'd by the caller using free(3). + * If the SHOW_GRANTED flag is set it will show granted and denied + * mls/validatetrans (the default is to show only those denied). + */ +extern int sepol_validate_transition_reason_buffer(sepol_security_id_t oldsid, + sepol_security_id_t newsid, + sepol_security_id_t tasksid, + sepol_security_class_t tclass, + char **reason_buf, + unsigned int flags); + +/* + * Return a class ID associated with the class string representation + * specified by `class_name'. + */ +extern int sepol_string_to_security_class(const char *class_name, + sepol_security_class_t *tclass); + +/* + * Return a permission av bit associated with tclass and the string + * representation of the `perm_name'. + */ +extern int sepol_string_to_av_perm(sepol_security_class_t tclass, + const char *perm_name, + sepol_access_vector_t *av); + +/* + * Return a string representation of the permission av bit associated with + * tclass. + * Returns a pointer to an internal buffer, overridden by the next call to + * this function or sepol_av_to_string(). + */ + extern const char *sepol_av_perm_to_string(sepol_security_class_t tclass, + sepol_access_vector_t av); + +/* + * Compute a SID to use for labeling a new object in the + * class `tclass' based on a SID pair. + */ +extern int sepol_transition_sid(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Compute a SID to use when selecting a member of a + * polyinstantiated object of class `tclass' based on + * a SID pair. + */ +extern int sepol_member_sid(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Compute a SID to use for relabeling an object in the + * class `tclass' based on a SID pair. + */ +extern int sepol_change_sid(sepol_security_id_t ssid, /* IN */ + sepol_security_id_t tsid, /* IN */ + sepol_security_class_t tclass, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Write the security context string representation of + * the context associated with `sid' into a dynamically + * allocated string of the correct size. Set `*scontext' + * to point to this string and set `*scontext_len' to + * the length of the string. + */ +extern int sepol_sid_to_context(sepol_security_id_t sid, /* IN */ + sepol_security_context_t * scontext, /* OUT */ + size_t * scontext_len); /* OUT */ + +/* + * Return a SID associated with the security context that + * has the string representation specified by `scontext'. + */ +extern int sepol_context_to_sid(sepol_const_security_context_t scontext, /* IN */ + size_t scontext_len, /* IN */ + sepol_security_id_t * out_sid); /* OUT */ + +/* + * Generate the set of SIDs for legal security contexts + * for a given user that can be reached by `fromsid'. + * Set `*sids' to point to a dynamically allocated + * array containing the set of SIDs. Set `*nel' to the + * number of elements in the array. + */ +extern int sepol_get_user_sids(sepol_security_id_t callsid, + char *username, + sepol_security_id_t ** sids, uint32_t * nel); + +/* + * Return the SIDs to use for an unlabeled file system + * that is being mounted from the device with the + * the kdevname `name'. The `fs_sid' SID is returned for + * the file system and the `file_sid' SID is returned + * for all files within that file system. + */ +extern int sepol_fs_sid(char *dev, /* IN */ + sepol_security_id_t * fs_sid, /* OUT */ + sepol_security_id_t * file_sid); /* OUT */ + +/* + * Return the SID of the port specified by + * `domain', `type', `protocol', and `port'. + */ +extern int sepol_port_sid(uint16_t domain, + uint16_t type, + uint8_t protocol, + uint16_t port, sepol_security_id_t * out_sid); + +/* + * Return the SID of the ibpkey specified by + * `subnet prefix', and `pkey'. + */ +extern int sepol_ibpkey_sid(uint64_t subnet_prefix_p, + uint16_t pkey, + sepol_security_id_t *out_sid); + +/* + * Return the SID of the ibendport specified by + * `dev_name', and `port'. + */ +extern int sepol_ibendport_sid(char *dev_name, + uint8_t port, + sepol_security_id_t *out_sid); + +/* + * Return the SIDs to use for a network interface + * with the name `name'. The `if_sid' SID is returned for + * the interface and the `msg_sid' SID is returned as + * the default SID for messages received on the + * interface. + */ +extern int sepol_netif_sid(char *name, + sepol_security_id_t * if_sid, + sepol_security_id_t * msg_sid); + +/* + * Return the SID of the node specified by the address + * `addr' where `addrlen' is the length of the address + * in bytes and `domain' is the communications domain or + * address family in which the address should be interpreted. + */ +extern int sepol_node_sid(uint16_t domain, + void *addr, + size_t addrlen, sepol_security_id_t * out_sid); + +/* + * Return a value indicating how to handle labeling for the + * the specified filesystem type, and optionally return a SID + * for the filesystem object. + */ +#define SECURITY_FS_USE_XATTR 1 /* use xattr */ +#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ +#define SECURITY_FS_USE_TASK 3 /* use task SIDs, e.g. pipefs/sockfs */ +#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */ +#define SECURITY_FS_USE_NONE 5 /* no labeling support */ +extern int sepol_fs_use(const char *fstype, /* IN */ + unsigned int *behavior, /* OUT */ + sepol_security_id_t * sid); /* OUT */ + +/* + * Return the SID to use for a file in a filesystem + * that cannot support a persistent label mapping or use another + * fixed labeling behavior like transition SIDs or task SIDs. + */ +extern int sepol_genfs_sid(const char *fstype, /* IN */ + const char *name, /* IN */ + sepol_security_class_t sclass, /* IN */ + sepol_security_id_t * sid); /* OUT */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/policydb/sidtab.h b/kernel/libsepol/include/sepol/policydb/sidtab.h new file mode 100644 index 00000000..893e6f0b --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/sidtab.h @@ -0,0 +1,79 @@ +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * A security identifier table (sidtab) is a hash table + * of security context structures indexed by SID value. + */ + +#ifndef _SEPOL_POLICYDB_SIDTAB_H_ +#define _SEPOL_POLICYDB_SIDTAB_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sidtab_node { + sepol_security_id_t sid; /* security identifier */ + context_struct_t context; /* security context structure */ + struct sidtab_node *next; +} sidtab_node_t; + +typedef struct sidtab_node *sidtab_ptr_t; + +#define SIDTAB_HASH_BITS 7 +#define SIDTAB_HASH_BUCKETS (1 << SIDTAB_HASH_BITS) +#define SIDTAB_HASH_MASK (SIDTAB_HASH_BUCKETS-1) + +#define SIDTAB_SIZE SIDTAB_HASH_BUCKETS + +typedef struct { + sidtab_ptr_t *htable; + unsigned int nel; /* number of elements */ + unsigned int next_sid; /* next SID to allocate */ + unsigned char shutdown; +} sidtab_t; + +extern int sepol_sidtab_init(sidtab_t * s); + +extern int sepol_sidtab_insert(sidtab_t * s, + sepol_security_id_t sid, + context_struct_t * context); + +extern context_struct_t *sepol_sidtab_search(sidtab_t * s, + sepol_security_id_t sid); + +extern int sepol_sidtab_map(sidtab_t * s, + int (*apply) (sepol_security_id_t sid, + context_struct_t * context, + void *args), void *args); + +extern void sepol_sidtab_map_remove_on_error(sidtab_t * s, + int (*apply) (sepol_security_id_t + s, + context_struct_t * + context, void *args), + void *args); + +extern int sepol_sidtab_context_to_sid(sidtab_t * s, /* IN */ + context_struct_t * context, /* IN */ + sepol_security_id_t * sid); /* OUT */ + +extern void sepol_sidtab_hash_eval(sidtab_t * h, char *tag); + +extern void sepol_sidtab_destroy(sidtab_t * s); + +extern void sepol_sidtab_set(sidtab_t * dst, sidtab_t * src); + +extern void sepol_sidtab_shutdown(sidtab_t * s); + +#ifdef __cplusplus +} +#endif + +#endif /* _SIDTAB_H_ */ + +/* FLASK */ diff --git a/kernel/libsepol/include/sepol/policydb/symtab.h b/kernel/libsepol/include/sepol/policydb/symtab.h new file mode 100644 index 00000000..fb410c63 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/symtab.h @@ -0,0 +1,47 @@ + +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * A symbol table (symtab) maintains associations between symbol + * strings and datum values. The type of the datum values + * is arbitrary. The symbol table type is implemented + * using the hash table type (hashtab). + */ + +#ifndef _SEPOL_POLICYDB_SYMTAB_H_ +#define _SEPOL_POLICYDB_SYMTAB_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The symtab_datum struct stores the common information for + * all symtab datums. It should the first element in every + * struct that will be used in a symtab to allow the specific + * datum types to be freely cast to this type. + * + * The values start at 1 - 0 is never a valid value. + */ +typedef struct symtab_datum { + uint32_t value; +} symtab_datum_t; + +typedef struct { + hashtab_t table; /* hash table (keyed on a string) */ + uint32_t nprim; /* number of primary names in table */ +} symtab_t; + +extern int ksu_symtab_init(symtab_t *, unsigned int size); +extern void symtab_destroy(symtab_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYMTAB_H_ */ + +/* FLASK */ diff --git a/kernel/libsepol/include/sepol/policydb/util.h b/kernel/libsepol/include/sepol/policydb/util.h new file mode 100644 index 00000000..ee236a25 --- /dev/null +++ b/kernel/libsepol/include/sepol/policydb/util.h @@ -0,0 +1,47 @@ +/* Authors: Karl MacMillan + * + * A set of utility functions that aid policy decision when dealing + * with hierarchal namespaces. + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SEPOL_UTIL_H__ +#define __SEPOL_UTIL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a); + +extern char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass, + sepol_access_vector_t av); + +char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms); + +/* + * The tokenize function may be used to + * replace sscanf + */ +extern int tokenize(char *line_buf, char delim, int num_args, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/port_record.h b/kernel/libsepol/include/sepol/port_record.h new file mode 100644 index 00000000..77149cfa --- /dev/null +++ b/kernel/libsepol/include/sepol/port_record.h @@ -0,0 +1,76 @@ +#ifndef _SEPOL_PORT_RECORD_H_ +#define _SEPOL_PORT_RECORD_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_port; +struct sepol_port_key; +typedef struct sepol_port sepol_port_t; +typedef struct sepol_port_key sepol_port_key_t; + +#define SEPOL_PROTO_UDP 0 +#define SEPOL_PROTO_TCP 1 +#define SEPOL_PROTO_DCCP 2 +#define SEPOL_PROTO_SCTP 3 + +/* Key */ +extern int sepol_port_compare(const sepol_port_t * port, + const sepol_port_key_t * key); + +extern int sepol_port_compare2(const sepol_port_t * port, + const sepol_port_t * port2); + +extern int sepol_port_key_create(sepol_handle_t * handle, + int low, int high, int proto, + sepol_port_key_t ** key_ptr); + +extern void sepol_port_key_unpack(const sepol_port_key_t * key, + int *low, int *high, int *proto); + +extern int sepol_port_key_extract(sepol_handle_t * handle, + const sepol_port_t * port, + sepol_port_key_t ** key_ptr); + +extern void sepol_port_key_free(sepol_port_key_t * key); + +/* Protocol */ +extern int sepol_port_get_proto(const sepol_port_t * port); + +extern void sepol_port_set_proto(sepol_port_t * port, int proto); + +extern const char *sepol_port_get_proto_str(int proto); + +/* Port */ +extern int sepol_port_get_low(const sepol_port_t * port); + +extern int sepol_port_get_high(const sepol_port_t * port); + +extern void sepol_port_set_port(sepol_port_t * port, int port_num); + +extern void sepol_port_set_range(sepol_port_t * port, int low, int high); + +/* Context */ +extern sepol_context_t *sepol_port_get_con(const sepol_port_t * port); + +extern int sepol_port_set_con(sepol_handle_t * handle, + sepol_port_t * port, sepol_context_t * con); + +/* Create/Clone/Destroy */ +extern int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port_ptr); + +extern int sepol_port_clone(sepol_handle_t * handle, + const sepol_port_t * port, + sepol_port_t ** port_ptr); + +extern void sepol_port_free(sepol_port_t * port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/ports.h b/kernel/libsepol/include/sepol/ports.h new file mode 100644 index 00000000..cda246c0 --- /dev/null +++ b/kernel/libsepol/include/sepol/ports.h @@ -0,0 +1,48 @@ +#ifndef _SEPOL_PORTS_H_ +#define _SEPOL_PORTS_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Return the number of ports */ +extern int sepol_port_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if a port exists */ +extern int sepol_port_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_port_key_t * key, int *response); + +/* Query a port - returns the port, or NULL if not found */ +extern int sepol_port_query(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_port_key_t * key, + sepol_port_t ** response); + +/* Modify a port, or add it, if the key is not found */ +extern int sepol_port_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_port_key_t * key, + const sepol_port_t * data); + +/* Iterate the ports + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_port_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_port_t * port, + void *fn_arg), void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/sepol.h b/kernel/libsepol/include/sepol/sepol.h new file mode 100644 index 00000000..4b68e4a9 --- /dev/null +++ b/kernel/libsepol/include/sepol/sepol.h @@ -0,0 +1,40 @@ +#ifndef _SEPOL_H_ +#define _SEPOL_H_ + +// #include +// #include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Set internal policydb from a file for subsequent service calls. */ +extern int sepol_set_policydb_from_file(FILE * fp); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/user_record.h b/kernel/libsepol/include/sepol/user_record.h new file mode 100644 index 00000000..d17a3db1 --- /dev/null +++ b/kernel/libsepol/include/sepol/user_record.h @@ -0,0 +1,84 @@ +#ifndef _SEPOL_USER_RECORD_H_ +#define _SEPOL_USER_RECORD_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sepol_user; +struct sepol_user_key; +typedef struct sepol_user sepol_user_t; +typedef struct sepol_user_key sepol_user_key_t; + +/* Key */ +extern int sepol_user_key_create(sepol_handle_t * handle, + const char *name, sepol_user_key_t ** key); + +extern void sepol_user_key_unpack(const sepol_user_key_t * key, + const char **name); + +extern int sepol_user_key_extract(sepol_handle_t * handle, + const sepol_user_t * user, + sepol_user_key_t ** key_ptr); + +extern void sepol_user_key_free(sepol_user_key_t * key); + +extern int sepol_user_compare(const sepol_user_t * user, + const sepol_user_key_t * key); + +extern int sepol_user_compare2(const sepol_user_t * user, + const sepol_user_t * user2); + +/* Name */ +extern const char *sepol_user_get_name(const sepol_user_t * user); + +extern int sepol_user_set_name(sepol_handle_t * handle, + sepol_user_t * user, const char *name); + +/* MLS */ +extern const char *sepol_user_get_mlslevel(const sepol_user_t * user); + +extern int sepol_user_set_mlslevel(sepol_handle_t * handle, + sepol_user_t * user, const char *mls_level); + +extern const char *sepol_user_get_mlsrange(const sepol_user_t * user); + +extern int sepol_user_set_mlsrange(sepol_handle_t * handle, + sepol_user_t * user, const char *mls_range); + +/* Role management */ +extern int sepol_user_get_num_roles(const sepol_user_t * user); + +extern int sepol_user_add_role(sepol_handle_t * handle, + sepol_user_t * user, const char *role); + +extern void sepol_user_del_role(sepol_user_t * user, const char *role); + +extern int sepol_user_has_role(const sepol_user_t * user, const char *role); + +extern int sepol_user_get_roles(sepol_handle_t * handle, + const sepol_user_t * user, + const char ***roles_arr, + unsigned int *num_roles); + +extern int sepol_user_set_roles(sepol_handle_t * handle, + sepol_user_t * user, + const char **roles_arr, unsigned int num_roles); + +/* Create/Clone/Destroy */ +extern int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr); + +extern int sepol_user_clone(sepol_handle_t * handle, + const sepol_user_t * user, + sepol_user_t ** user_ptr); + +extern void sepol_user_free(sepol_user_t * user); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/include/sepol/users.h b/kernel/libsepol/include/sepol/users.h new file mode 100644 index 00000000..156d1adb --- /dev/null +++ b/kernel/libsepol/include/sepol/users.h @@ -0,0 +1,48 @@ +#ifndef _SEPOL_USERS_H_ +#define _SEPOL_USERS_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Modify the user, or add it, if the key is not found */ +extern int sepol_user_modify(sepol_handle_t * handle, + sepol_policydb_t * policydb, + const sepol_user_key_t * key, + const sepol_user_t * data); + +/* Return the number of users */ +extern int sepol_user_count(sepol_handle_t * handle, + const sepol_policydb_t * p, unsigned int *response); + +/* Check if the specified user exists */ +extern int sepol_user_exists(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_user_key_t * key, int *response); + +/* Query a user - returns the user or NULL if not found */ +extern int sepol_user_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_user_key_t * key, + sepol_user_t ** response); + +/* Iterate the users + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ +extern int sepol_user_iterate(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + int (*fn) (const sepol_user_t * user, + void *fn_arg), void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/libsepol/man/.DS_Store b/kernel/libsepol/man/.DS_Store new file mode 100644 index 00000000..c938112a Binary files /dev/null and b/kernel/libsepol/man/.DS_Store differ diff --git a/kernel/libsepol/man/Makefile b/kernel/libsepol/man/Makefile new file mode 100644 index 00000000..f54e478d --- /dev/null +++ b/kernel/libsepol/man/Makefile @@ -0,0 +1,26 @@ +# Installation directories. +LINGUAS ?= ru +PREFIX ?= /usr +MANDIR ?= $(PREFIX)/share/man +MAN3SUBDIR ?= man3 +MAN8SUBDIR ?= man8 +MAN3DIR ?= $(MANDIR)/$(MAN3SUBDIR) +MAN8DIR ?= $(MANDIR)/$(MAN8SUBDIR) + +all: + +install: all + mkdir -p $(DESTDIR)$(MAN3DIR) + mkdir -p $(DESTDIR)$(MAN8DIR) + install -m 644 man3/*.3 $(DESTDIR)$(MAN3DIR) + install -m 644 man8/*.8 $(DESTDIR)$(MAN8DIR) + for lang in $(LINGUAS) ; do \ + if [ -e $${lang}/man3 ] ; then \ + mkdir -p $(DESTDIR)$(MANDIR)/$${lang}/$(MAN3SUBDIR) ; \ + install -m 644 $${lang}/man3/*.3 $(DESTDIR)$(MANDIR)/$${lang}/$(MAN3SUBDIR) ; \ + fi ; \ + if [ -e $${lang}/man8 ] ; then \ + mkdir -p $(DESTDIR)$(MANDIR)/$${lang}/$(MAN8SUBDIR) ; \ + install -m 644 $${lang}/man8/*.8 $(DESTDIR)$(MANDIR)/$${lang}/$(MAN8SUBDIR) ; \ + fi ; \ + done diff --git a/kernel/libsepol/man/man3/sepol_check_context.3 b/kernel/libsepol/man/man3/sepol_check_context.3 new file mode 100644 index 00000000..4a3c57d1 --- /dev/null +++ b/kernel/libsepol/man/man3/sepol_check_context.3 @@ -0,0 +1,25 @@ +.TH "sepol_check_context" "3" "15 March 2005" "sds@tycho.nsa.gov" "SE Linux binary policy API documentation" +.SH "NAME" +sepol_check_context \- Check the validity of a security context against a binary policy. +.SH "SYNOPSIS" +.B #include +.sp +.BI "int sepol_check_context(const char *" context ");" +.sp +.BI "int sepol_set_policydb_from_file(FILE *" fp ");" + +.SH "DESCRIPTION" +.B sepol_check_context +checks the validity of a security context against a binary policy +previously loaded from a file via +.B sepol_set_policydb_from_file. +It is used by +.B setfiles -c +to validate a file contexts configuration against the binary policy +upon policy builds. For validating a context against the active +policy on a SELinux system, use +.B security_check_context +from libselinux instead. + +.SH "RETURN VALUE" +Returns 0 on success or \-1 with errno set otherwise. diff --git a/kernel/libsepol/man/man8/chkcon.8 b/kernel/libsepol/man/man8/chkcon.8 new file mode 100644 index 00000000..f8d75df2 --- /dev/null +++ b/kernel/libsepol/man/man8/chkcon.8 @@ -0,0 +1,41 @@ +.\" Hey, Emacs! This is an -*- nroff -*- source file. +.\" Copyright (c) 1997 Manoj Srivastava +.\" +.\" This is free documentation; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of +.\" the License, or (at your option) any later version. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with this manual; if not, write to the Free +.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, +.\" USA. +.\" +.TH CHKCON 8 "Mar 12 2005" "SELinux" "SELinux Command Line documentation" +.SH NAME +chkcon \- determine if a security context is valid for a given binary policy +.SH SYNOPSIS +chkcon policy_file context +.SH DESCRIPTION +This utility validates (the string representation of) a security context +specified by the argument +.I context +against configuration data read in from a policy database binary +representation file specified by the argument +.I policy_file. +.SH FILES +policy file +.SH AUTHOR +This manual page (and just the manual page) was written by Manoj +Srivastava . + diff --git a/kernel/libsepol/man/man8/genpolbools.8 b/kernel/libsepol/man/man8/genpolbools.8 new file mode 100644 index 00000000..fc792c8c --- /dev/null +++ b/kernel/libsepol/man/man8/genpolbools.8 @@ -0,0 +1,16 @@ +.TH "genpolbools" "8" "11 August 2004" "sds@tycho.nsa.gov" "SELinux Command Line documentation" +.SH "NAME" +genpolbools \- Rewrite a binary policy with different boolean settings +.SH "SYNOPSIS" +.B genpolbools oldpolicy booleans newpolicy + +.SH "DESCRIPTION" +.B genpolbools +rewrites an existing binary policy with different boolean settings, +generating a new binary policy. The booleans file specifies the +different boolean settings using name=value lines, where value +can be 0 or false to disable the boolean or 1 or true to enable it. + + + + diff --git a/kernel/libsepol/man/man8/genpolusers.8 b/kernel/libsepol/man/man8/genpolusers.8 new file mode 100644 index 00000000..34d729af --- /dev/null +++ b/kernel/libsepol/man/man8/genpolusers.8 @@ -0,0 +1,42 @@ +.\" Hey, Emacs! This is an -*- nroff -*- source file. +.\" Copyright (c) 1997 Manoj Srivastava +.\" +.\" This is free documentation; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of +.\" the License, or (at your option) any later version. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with this manual; if not, write to the Free +.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, +.\" USA. +.\" +.TH GENPOLUSERS 8 "Mar 12 2005" "SELinux" "SELinux Command Line documentation" +.SH NAME +genpolusers \- Generate new binary policy with updated user configuration +.SH SYNOPSIS +genpolusers in-policy usersdir out-policy +.SH DESCRIPTION +Given an existing binary policy file +.I in\-policy, +generate a new binary policy +.I out\-policy +with an updated user configuration based on any +.B system.users +and +.B local.users +files in the specified +.I usersdir. +.SH AUTHOR +This manual page (and just the manual page) was written by Manoj +Srivastava . diff --git a/kernel/libsepol/man/ru/.DS_Store b/kernel/libsepol/man/ru/.DS_Store new file mode 100644 index 00000000..1b8272e3 Binary files /dev/null and b/kernel/libsepol/man/ru/.DS_Store differ diff --git a/kernel/libsepol/man/ru/man8/chkcon.8 b/kernel/libsepol/man/ru/man8/chkcon.8 new file mode 100644 index 00000000..2661afb0 --- /dev/null +++ b/kernel/libsepol/man/ru/man8/chkcon.8 @@ -0,0 +1,39 @@ +.\" Hey, Emacs! This is an -*- nroff -*- source file. +.\" Copyright (c) 1997 Manoj Srivastava +.\" +.\" This is free documentation; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2 of +.\" the License, or (at your option) any later version. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with this manual; if not, write to the Free +.\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, +.\" USA. +.\" +.TH CHKCON 8 "12 марта 2005" "SELinux" "Документация по командной строке SELinux" +.SH ИМЯ +chkcon \- определить, является ли контекст безопасности действительным для конкретной двоичной политики +.SH ОБЗОР +chkcon policy_file context +.SH ОПИСАНИЕ +Эта утилита проверяет контекст безопасности (его строковое представление), заданный аргументом +.I context, +относительно данных конфигурации, прочтённых из файла двоичного представления базы данных политик, заданного аргументом +.I policy_file. +.SH ФАЙЛЫ +policy file +.SH АВТОРЫ +Эта страница руководства (и только она) была написана Manoj +Srivastava . +Перевод на русский язык выполнила Герасименко Олеся . diff --git a/kernel/libsepol/modules.order b/kernel/libsepol/modules.order new file mode 100644 index 00000000..e69de29b diff --git a/kernel/libsepol/src/.assertion.o.cmd b/kernel/libsepol/src/.assertion.o.cmd new file mode 100644 index 00000000..439efefc --- /dev/null +++ b/kernel/libsepol/src/.assertion.o.cmd @@ -0,0 +1,608 @@ +cmd_/data/libkernelsepol/libsepol/src/assertion.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.assertion.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"assertion"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_assertion.o /data/libkernelsepol/libsepol/src/assertion.c + +source_/data/libkernelsepol/libsepol/src/assertion.o := /data/libkernelsepol/libsepol/src/assertion.c + +deps_/data/libkernelsepol/libsepol/src/assertion.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/util.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + +/data/libkernelsepol/libsepol/src/assertion.o: $(deps_/data/libkernelsepol/libsepol/src/assertion.o) + +$(deps_/data/libkernelsepol/libsepol/src/assertion.o): diff --git a/kernel/libsepol/src/.avrule_block.o.cmd b/kernel/libsepol/src/.avrule_block.o.cmd new file mode 100644 index 00000000..d58cbe1c --- /dev/null +++ b/kernel/libsepol/src/.avrule_block.o.cmd @@ -0,0 +1,603 @@ +cmd_/data/libkernelsepol/libsepol/src/avrule_block.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.avrule_block.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"avrule_block"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_avrule_block.o /data/libkernelsepol/libsepol/src/avrule_block.c + +source_/data/libkernelsepol/libsepol/src/avrule_block.o := /data/libkernelsepol/libsepol/src/avrule_block.c + +deps_/data/libkernelsepol/libsepol/src/avrule_block.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avrule_block.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/avrule_block.o: $(deps_/data/libkernelsepol/libsepol/src/avrule_block.o) + +$(deps_/data/libkernelsepol/libsepol/src/avrule_block.o): diff --git a/kernel/libsepol/src/.avtab.o.cmd b/kernel/libsepol/src/.avtab.o.cmd new file mode 100644 index 00000000..0f66e206 --- /dev/null +++ b/kernel/libsepol/src/.avtab.o.cmd @@ -0,0 +1,605 @@ +cmd_/data/libkernelsepol/libsepol/src/avtab.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.avtab.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"avtab"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_avtab.o /data/libkernelsepol/libsepol/src/avtab.c + +source_/data/libkernelsepol/libsepol/src/avtab.o := /data/libkernelsepol/libsepol/src/avtab.c + +deps_/data/libkernelsepol/libsepol/src/avtab.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + +/data/libkernelsepol/libsepol/src/avtab.o: $(deps_/data/libkernelsepol/libsepol/src/avtab.o) + +$(deps_/data/libkernelsepol/libsepol/src/avtab.o): diff --git a/kernel/libsepol/src/.boolean_record.o.cmd b/kernel/libsepol/src/.boolean_record.o.cmd new file mode 100644 index 00000000..1137ed1a --- /dev/null +++ b/kernel/libsepol/src/.boolean_record.o.cmd @@ -0,0 +1,594 @@ +cmd_/data/libkernelsepol/libsepol/src/boolean_record.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.boolean_record.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"boolean_record"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_boolean_record.o /data/libkernelsepol/libsepol/src/boolean_record.c + +source_/data/libkernelsepol/libsepol/src/boolean_record.o := /data/libkernelsepol/libsepol/src/boolean_record.c + +deps_/data/libkernelsepol/libsepol/src/boolean_record.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/src/boolean_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/boolean_record.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/booleans.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/boolean_record.o: $(deps_/data/libkernelsepol/libsepol/src/boolean_record.o) + +$(deps_/data/libkernelsepol/libsepol/src/boolean_record.o): diff --git a/kernel/libsepol/src/.booleans.o.cmd b/kernel/libsepol/src/.booleans.o.cmd new file mode 100644 index 00000000..bac832c5 --- /dev/null +++ b/kernel/libsepol/src/.booleans.o.cmd @@ -0,0 +1,609 @@ +cmd_/data/libkernelsepol/libsepol/src/booleans.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.booleans.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"booleans"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_booleans.o /data/libkernelsepol/libsepol/src/booleans.c + +source_/data/libkernelsepol/libsepol/src/booleans.o := /data/libkernelsepol/libsepol/src/booleans.c + +deps_/data/libkernelsepol/libsepol/src/booleans.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/booleans.h \ + /data/libkernelsepol/libsepol/include/sepol/boolean_record.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/src/boolean_internal.h \ + +/data/libkernelsepol/libsepol/src/booleans.o: $(deps_/data/libkernelsepol/libsepol/src/booleans.o) + +$(deps_/data/libkernelsepol/libsepol/src/booleans.o): diff --git a/kernel/libsepol/src/.conditional.o.cmd b/kernel/libsepol/src/.conditional.o.cmd new file mode 100644 index 00000000..9354a3ec --- /dev/null +++ b/kernel/libsepol/src/.conditional.o.cmd @@ -0,0 +1,606 @@ +cmd_/data/libkernelsepol/libsepol/src/conditional.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.conditional.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"conditional"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_conditional.o /data/libkernelsepol/libsepol/src/conditional.c + +source_/data/libkernelsepol/libsepol/src/conditional.o := /data/libkernelsepol/libsepol/src/conditional.c + +deps_/data/libkernelsepol/libsepol/src/conditional.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + +/data/libkernelsepol/libsepol/src/conditional.o: $(deps_/data/libkernelsepol/libsepol/src/conditional.o) + +$(deps_/data/libkernelsepol/libsepol/src/conditional.o): diff --git a/kernel/libsepol/src/.constraint.o.cmd b/kernel/libsepol/src/.constraint.o.cmd new file mode 100644 index 00000000..a6181035 --- /dev/null +++ b/kernel/libsepol/src/.constraint.o.cmd @@ -0,0 +1,603 @@ +cmd_/data/libkernelsepol/libsepol/src/constraint.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.constraint.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"constraint"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_constraint.o /data/libkernelsepol/libsepol/src/constraint.c + +source_/data/libkernelsepol/libsepol/src/constraint.o := /data/libkernelsepol/libsepol/src/constraint.c + +deps_/data/libkernelsepol/libsepol/src/constraint.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/constraint.o: $(deps_/data/libkernelsepol/libsepol/src/constraint.o) + +$(deps_/data/libkernelsepol/libsepol/src/constraint.o): diff --git a/kernel/libsepol/src/.context.o.cmd b/kernel/libsepol/src/.context.o.cmd new file mode 100644 index 00000000..3803150c --- /dev/null +++ b/kernel/libsepol/src/.context.o.cmd @@ -0,0 +1,612 @@ +cmd_/data/libkernelsepol/libsepol/src/context.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.context.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"context"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_context.o /data/libkernelsepol/libsepol/src/context.c + +source_/data/libkernelsepol/libsepol/src/context.o := /data/libkernelsepol/libsepol/src/context.c + +deps_/data/libkernelsepol/libsepol/src/context.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/services.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/context.h \ + /data/libkernelsepol/libsepol/src/mls.h \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + /data/libkernelsepol/libsepol/src/private.h \ + +/data/libkernelsepol/libsepol/src/context.o: $(deps_/data/libkernelsepol/libsepol/src/context.o) + +$(deps_/data/libkernelsepol/libsepol/src/context.o): diff --git a/kernel/libsepol/src/.context_record.o.cmd b/kernel/libsepol/src/.context_record.o.cmd new file mode 100644 index 00000000..05ac1aa8 --- /dev/null +++ b/kernel/libsepol/src/.context_record.o.cmd @@ -0,0 +1,608 @@ +cmd_/data/libkernelsepol/libsepol/src/context_record.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.context_record.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"context_record"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_context_record.o /data/libkernelsepol/libsepol/src/context_record.c + +source_/data/libkernelsepol/libsepol/src/context_record.o := /data/libkernelsepol/libsepol/src/context_record.c + +deps_/data/libkernelsepol/libsepol/src/context_record.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + +/data/libkernelsepol/libsepol/src/context_record.o: $(deps_/data/libkernelsepol/libsepol/src/context_record.o) + +$(deps_/data/libkernelsepol/libsepol/src/context_record.o): diff --git a/kernel/libsepol/src/.debug.o.cmd b/kernel/libsepol/src/.debug.o.cmd new file mode 100644 index 00000000..5a0de9f4 --- /dev/null +++ b/kernel/libsepol/src/.debug.o.cmd @@ -0,0 +1,589 @@ +cmd_/data/libkernelsepol/libsepol/src/debug.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.debug.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"debug"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_debug.o /data/libkernelsepol/libsepol/src/debug.c + +source_/data/libkernelsepol/libsepol/src/debug.o := /data/libkernelsepol/libsepol/src/debug.c + +deps_/data/libkernelsepol/libsepol/src/debug.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/kasan.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/smp.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/x86/32.h) \ + $(wildcard include/config/debug/bugverbose.h) \ + include/linux/stringify.h \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + $(wildcard include/config/jump/label.h) \ + include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/debug.o: $(deps_/data/libkernelsepol/libsepol/src/debug.o) + +$(deps_/data/libkernelsepol/libsepol/src/debug.o): diff --git a/kernel/libsepol/src/.ebitmap.o.cmd b/kernel/libsepol/src/.ebitmap.o.cmd new file mode 100644 index 00000000..8c6f41cc --- /dev/null +++ b/kernel/libsepol/src/.ebitmap.o.cmd @@ -0,0 +1,605 @@ +cmd_/data/libkernelsepol/libsepol/src/ebitmap.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.ebitmap.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"ebitmap"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_ebitmap.o /data/libkernelsepol/libsepol/src/ebitmap.c + +source_/data/libkernelsepol/libsepol/src/ebitmap.o := /data/libkernelsepol/libsepol/src/ebitmap.c + +deps_/data/libkernelsepol/libsepol/src/ebitmap.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + +/data/libkernelsepol/libsepol/src/ebitmap.o: $(deps_/data/libkernelsepol/libsepol/src/ebitmap.o) + +$(deps_/data/libkernelsepol/libsepol/src/ebitmap.o): diff --git a/kernel/libsepol/src/.expand.o.cmd b/kernel/libsepol/src/.expand.o.cmd new file mode 100644 index 00000000..17d207b7 --- /dev/null +++ b/kernel/libsepol/src/.expand.o.cmd @@ -0,0 +1,613 @@ +cmd_/data/libkernelsepol/libsepol/src/expand.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.expand.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"expand"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_expand.o /data/libkernelsepol/libsepol/src/expand.c + +source_/data/libkernelsepol/libsepol/src/expand.o := /data/libkernelsepol/libsepol/src/expand.c + +deps_/data/libkernelsepol/libsepol/src/expand.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/src/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hierarchy.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avrule_block.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + +/data/libkernelsepol/libsepol/src/expand.o: $(deps_/data/libkernelsepol/libsepol/src/expand.o) + +$(deps_/data/libkernelsepol/libsepol/src/expand.o): diff --git a/kernel/libsepol/src/.handle.o.cmd b/kernel/libsepol/src/.handle.o.cmd new file mode 100644 index 00000000..03645615 --- /dev/null +++ b/kernel/libsepol/src/.handle.o.cmd @@ -0,0 +1,589 @@ +cmd_/data/libkernelsepol/libsepol/src/handle.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.handle.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"handle"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_handle.o /data/libkernelsepol/libsepol/src/handle.c + +source_/data/libkernelsepol/libsepol/src/handle.o := /data/libkernelsepol/libsepol/src/handle.c + +deps_/data/libkernelsepol/libsepol/src/handle.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/kasan.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/smp.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/x86/32.h) \ + $(wildcard include/config/debug/bugverbose.h) \ + include/linux/stringify.h \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + $(wildcard include/config/jump/label.h) \ + include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/handle.o: $(deps_/data/libkernelsepol/libsepol/src/handle.o) + +$(deps_/data/libkernelsepol/libsepol/src/handle.o): diff --git a/kernel/libsepol/src/.hashtab.o.cmd b/kernel/libsepol/src/.hashtab.o.cmd new file mode 100644 index 00000000..a4c6f150 --- /dev/null +++ b/kernel/libsepol/src/.hashtab.o.cmd @@ -0,0 +1,602 @@ +cmd_/data/libkernelsepol/libsepol/src/hashtab.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.hashtab.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"hashtab"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_hashtab.o /data/libkernelsepol/libsepol/src/hashtab.c + +source_/data/libkernelsepol/libsepol/src/hashtab.o := /data/libkernelsepol/libsepol/src/hashtab.c + +deps_/data/libkernelsepol/libsepol/src/hashtab.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/hashtab.o: $(deps_/data/libkernelsepol/libsepol/src/hashtab.o) + +$(deps_/data/libkernelsepol/libsepol/src/hashtab.o): diff --git a/kernel/libsepol/src/.hierarchy.o.cmd b/kernel/libsepol/src/.hierarchy.o.cmd new file mode 100644 index 00000000..16a604a0 --- /dev/null +++ b/kernel/libsepol/src/.hierarchy.o.cmd @@ -0,0 +1,608 @@ +cmd_/data/libkernelsepol/libsepol/src/hierarchy.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.hierarchy.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"hierarchy"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_hierarchy.o /data/libkernelsepol/libsepol/src/hierarchy.c + +source_/data/libkernelsepol/libsepol/src/hierarchy.o := /data/libkernelsepol/libsepol/src/hierarchy.c + +deps_/data/libkernelsepol/libsepol/src/hierarchy.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hierarchy.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/util.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/hierarchy.o: $(deps_/data/libkernelsepol/libsepol/src/hierarchy.o) + +$(deps_/data/libkernelsepol/libsepol/src/hierarchy.o): diff --git a/kernel/libsepol/src/.inet_ntop.o.cmd b/kernel/libsepol/src/.inet_ntop.o.cmd new file mode 100644 index 00000000..fe5a5593 --- /dev/null +++ b/kernel/libsepol/src/.inet_ntop.o.cmd @@ -0,0 +1,1016 @@ +cmd_/data/libkernelsepol/libsepol/src/inet_ntop.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.inet_ntop.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"inet_ntop"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_inet_ntop.o /data/libkernelsepol/libsepol/src/inet_ntop.c + +source_/data/libkernelsepol/libsepol/src/inet_ntop.o := /data/libkernelsepol/libsepol/src/inet_ntop.c + +deps_/data/libkernelsepol/libsepol/src/inet_ntop.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + include/linux/socket.h \ + $(wildcard include/config/proc/fs.h) \ + $(wildcard include/config/compat.h) \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/linux/linkage.h \ + include/linux/stringify.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/64.h) \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + $(wildcard include/config/kasan.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + $(wildcard include/config/jump/label.h) \ + include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h \ + include/linux/build_bug.h \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/restart_block.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + $(wildcard include/config/sparsemem.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + include/linux/in.h \ + include/uapi/linux/in.h \ + include/uapi/linux/libc-compat.h \ + $(wildcard include/config/data.h) \ + include/linux/inet.h \ + include/net/net_namespace.h \ + $(wildcard include/config/nf/conntrack.h) \ + $(wildcard include/config/sysctl.h) \ + $(wildcard include/config/ipv6.h) \ + $(wildcard include/config/ieee802154/6lowpan.h) \ + $(wildcard include/config/ip/sctp.h) \ + $(wildcard include/config/ip/dccp.h) \ + $(wildcard include/config/netfilter.h) \ + $(wildcard include/config/nf/tables.h) \ + $(wildcard include/config/nf/defrag/ipv6.h) \ + $(wildcard include/config/netfilter/netlink/acct.h) \ + $(wildcard include/config/nf/ct/netlink/timeout.h) \ + $(wildcard include/config/wext/core.h) \ + $(wildcard include/config/xfrm.h) \ + $(wildcard include/config/ip/vs.h) \ + $(wildcard include/config/mpls.h) \ + $(wildcard include/config/can.h) \ + $(wildcard include/config/net/ns.h) \ + include/linux/refcount.h \ + $(wildcard include/config/refcount/full.h) \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + include/linux/spinlock_types.h \ + $(wildcard include/config/debug/spinlock.h) \ + include/linux/lockdep.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/preempt.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + arch/x86/include/asm/preempt.h \ + include/linux/bottom_half.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + arch/x86/include/asm/refcount.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/seqlock.h \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/sysctl.h \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/rbtree.h \ + include/linux/uidgid.h \ + $(wildcard include/config/multiuser.h) \ + $(wildcard include/config/user/ns.h) \ + include/linux/highuid.h \ + include/uapi/linux/sysctl.h \ + include/net/flow.h \ + include/linux/in6.h \ + include/uapi/linux/in6.h \ + include/net/flow_dissector.h \ + include/linux/siphash.h \ + $(wildcard include/config/have/efficient/unaligned/access.h) \ + include/uapi/linux/if_ether.h \ + include/net/netns/core.h \ + include/net/netns/mib.h \ + $(wildcard include/config/xfrm/statistics.h) \ + include/net/snmp.h \ + include/uapi/linux/snmp.h \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/numa/emu.h) \ + include/linux/nodemask.h \ + $(wildcard include/config/highmem.h) \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/u64_stats_sync.h \ + include/net/netns/unix.h \ + include/net/netns/packet.h \ + include/linux/rculist.h \ + include/net/netns/ipv4.h \ + $(wildcard include/config/ip/multiple/tables.h) \ + $(wildcard include/config/ip/route/classid.h) \ + $(wildcard include/config/security.h) \ + $(wildcard include/config/net/l3/master/dev.h) \ + $(wildcard include/config/ip/mroute.h) \ + $(wildcard include/config/ip/mroute/multiple/tables.h) \ + $(wildcard include/config/ip/route/multipath.h) \ + include/net/inet_frag.h \ + include/linux/rhashtable.h \ + include/linux/jhash.h \ + include/linux/unaligned/packed_struct.h \ + include/linux/list_nulls.h \ + include/net/netns/ipv6.h \ + $(wildcard include/config/ipv6/multiple/tables.h) \ + $(wildcard include/config/ipv6/mroute.h) \ + $(wildcard include/config/ipv6/mroute/multiple/tables.h) \ + include/net/dst_ops.h \ + include/linux/percpu_counter.h \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/gfp.h \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/net/netns/ieee802154_6lowpan.h \ + include/net/netns/sctp.h \ + include/net/netns/dccp.h \ + include/net/netns/netfilter.h \ + $(wildcard include/config/nf/defrag/ipv4.h) \ + include/linux/netfilter_defs.h \ + include/uapi/linux/netfilter.h \ + include/net/netns/x_tables.h \ + $(wildcard include/config/bridge/nf/ebtables.h) \ + include/net/netns/conntrack.h \ + $(wildcard include/config/nf/ct/proto/dccp.h) \ + $(wildcard include/config/nf/ct/proto/sctp.h) \ + $(wildcard include/config/nf/conntrack/events.h) \ + $(wildcard include/config/nf/conntrack/labels.h) \ + include/linux/netfilter/nf_conntrack_tcp.h \ + include/uapi/linux/netfilter/nf_conntrack_tcp.h \ + include/linux/netfilter/nf_conntrack_dccp.h \ + include/uapi/linux/netfilter/nf_conntrack_tuple_common.h \ + include/linux/netfilter/nf_conntrack_common.h \ + include/uapi/linux/netfilter/nf_conntrack_common.h \ + include/linux/netfilter/nf_conntrack_sctp.h \ + include/uapi/linux/netfilter/nf_conntrack_sctp.h \ + include/net/netns/nftables.h \ + include/net/netns/xfrm.h \ + include/uapi/linux/xfrm.h \ + include/net/netns/mpls.h \ + include/net/netns/can.h \ + include/linux/ns_common.h \ + include/linux/idr.h \ + include/linux/radix-tree.h \ + $(wildcard include/config/radix/tree/multiorder.h) \ + include/linux/skbuff.h \ + $(wildcard include/config/bridge/netfilter.h) \ + $(wildcard include/config/ipv6/ndisc/nodetype.h) \ + $(wildcard include/config/net/switchdev.h) \ + $(wildcard include/config/net/cls/act.h) \ + $(wildcard include/config/net/sched.h) \ + $(wildcard include/config/net/rx/busy/poll.h) \ + $(wildcard include/config/xps.h) \ + $(wildcard include/config/network/secmark.h) \ + $(wildcard include/config/network/phy/timestamping.h) \ + $(wildcard include/config/netfilter/xt/target/trace.h) \ + include/linux/net.h \ + include/linux/random.h \ + $(wildcard include/config/gcc/plugin/latent/entropy.h) \ + $(wildcard include/config/arch/random.h) \ + include/linux/once.h \ + include/uapi/linux/random.h \ + include/linux/irqnr.h \ + include/uapi/linux/irqnr.h \ + include/linux/prandom.h \ + arch/x86/include/asm/archrandom.h \ + include/linux/fcntl.h \ + include/uapi/linux/fcntl.h \ + arch/x86/include/uapi/asm/fcntl.h \ + include/uapi/asm-generic/fcntl.h \ + include/linux/fs.h \ + $(wildcard include/config/fs/posix/acl.h) \ + $(wildcard include/config/cgroup/writeback.h) \ + $(wildcard include/config/ima.h) \ + $(wildcard include/config/fsnotify.h) \ + $(wildcard include/config/fs/encryption.h) \ + $(wildcard include/config/epoll.h) \ + $(wildcard include/config/file/locking.h) \ + $(wildcard include/config/quota.h) \ + $(wildcard include/config/blk/dev/loop.h) \ + $(wildcard include/config/fs/dax.h) \ + $(wildcard include/config/block.h) \ + $(wildcard include/config/mandatory/file/locking.h) \ + $(wildcard include/config/migration.h) \ + include/linux/wait_bit.h \ + include/linux/kdev_t.h \ + include/uapi/linux/kdev_t.h \ + include/linux/dcache.h \ + include/linux/rculist_bl.h \ + include/linux/list_bl.h \ + include/linux/bit_spinlock.h \ + include/linux/lockref.h \ + $(wildcard include/config/arch/use/cmpxchg/lockref.h) \ + include/linux/stringhash.h \ + $(wildcard include/config/dcache/word/access.h) \ + include/linux/hash.h \ + $(wildcard include/config/have/arch/hash.h) \ + include/linux/path.h \ + include/linux/stat.h \ + arch/x86/include/uapi/asm/stat.h \ + include/uapi/linux/stat.h \ + include/linux/list_lru.h \ + $(wildcard include/config/slob.h) \ + include/linux/shrinker.h \ + include/linux/pid.h \ + include/linux/mm_types.h \ + $(wildcard include/config/have/cmpxchg/double.h) \ + $(wildcard include/config/have/aligned/struct/page.h) \ + $(wildcard include/config/userfaultfd.h) \ + $(wildcard include/config/have/arch/compat/mmap/bases.h) \ + $(wildcard include/config/membarrier.h) \ + $(wildcard include/config/aio.h) \ + $(wildcard include/config/mmu/notifier.h) \ + $(wildcard include/config/arch/want/batched/unmap/tlb/flush.h) \ + $(wildcard include/config/hmm.h) \ + include/linux/mm_types_task.h \ + $(wildcard include/config/split/ptlock/cpus.h) \ + $(wildcard include/config/arch/enable/split/pmd/ptlock.h) \ + arch/x86/include/asm/tlbbatch.h \ + include/linux/auxvec.h \ + include/uapi/linux/auxvec.h \ + arch/x86/include/uapi/asm/auxvec.h \ + include/linux/uprobes.h \ + $(wildcard include/config/uprobes.h) \ + arch/x86/include/asm/uprobes.h \ + include/linux/capability.h \ + include/uapi/linux/capability.h \ + include/linux/semaphore.h \ + include/uapi/linux/fiemap.h \ + include/linux/migrate_mode.h \ + include/linux/percpu-rwsem.h \ + include/linux/rcuwait.h \ + include/linux/rcu_sync.h \ + include/linux/delayed_call.h \ + include/linux/uuid.h \ + include/uapi/linux/uuid.h \ + include/linux/errseq.h \ + include/uapi/linux/fs.h \ + include/uapi/linux/limits.h \ + include/linux/quota.h \ + $(wildcard include/config/quota/netlink/interface.h) \ + include/uapi/linux/dqblk_xfs.h \ + include/linux/dqblk_v1.h \ + include/linux/dqblk_v2.h \ + include/linux/dqblk_qtree.h \ + include/linux/projid.h \ + include/uapi/linux/quota.h \ + include/linux/nfs_fs_i.h \ + include/uapi/linux/net.h \ + include/linux/textsearch.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/net/checksum.h \ + include/linux/uaccess.h \ + include/linux/sched.h \ + $(wildcard include/config/virt/cpu/accounting/native.h) \ + $(wildcard include/config/sched/info.h) \ + $(wildcard include/config/schedstats.h) \ + $(wildcard include/config/fair/group/sched.h) \ + $(wildcard include/config/rt/group/sched.h) \ + $(wildcard include/config/cgroup/sched.h) \ + $(wildcard include/config/blk/dev/io/trace.h) \ + $(wildcard include/config/compat/brk.h) \ + $(wildcard include/config/cgroups.h) \ + $(wildcard include/config/arch/has/scaled/cputime.h) \ + $(wildcard include/config/virt/cpu/accounting/gen.h) \ + $(wildcard include/config/posix/timers.h) \ + $(wildcard include/config/sysvipc.h) \ + $(wildcard include/config/detect/hung/task.h) \ + $(wildcard include/config/auditsyscall.h) \ + $(wildcard include/config/rt/mutexes.h) \ + $(wildcard include/config/ubsan.h) \ + $(wildcard include/config/task/xacct.h) \ + $(wildcard include/config/cpusets.h) \ + $(wildcard include/config/intel/rdt.h) \ + $(wildcard include/config/futex.h) \ + $(wildcard include/config/perf/events.h) \ + $(wildcard include/config/task/delay/acct.h) \ + $(wildcard include/config/fault/injection.h) \ + $(wildcard include/config/latencytop.h) \ + $(wildcard include/config/function/graph/tracer.h) \ + $(wildcard include/config/kcov.h) \ + $(wildcard include/config/bcache.h) \ + $(wildcard include/config/vmap/stack.h) \ + $(wildcard include/config/livepatch.h) \ + include/uapi/linux/sched.h \ + include/linux/sem.h \ + include/uapi/linux/sem.h \ + include/linux/ipc.h \ + include/uapi/linux/ipc.h \ + arch/x86/include/uapi/asm/ipcbuf.h \ + include/uapi/asm-generic/ipcbuf.h \ + arch/x86/include/uapi/asm/sembuf.h \ + include/linux/shm.h \ + include/uapi/linux/shm.h \ + include/uapi/asm-generic/hugetlb_encode.h \ + arch/x86/include/uapi/asm/shmbuf.h \ + include/uapi/asm-generic/shmbuf.h \ + arch/x86/include/asm/shmparam.h \ + include/linux/kcov.h \ + include/uapi/linux/kcov.h \ + include/linux/plist.h \ + $(wildcard include/config/debug/pi/list.h) \ + include/linux/hrtimer.h \ + $(wildcard include/config/high/res/timers.h) \ + $(wildcard include/config/time/low/res.h) \ + $(wildcard include/config/timerfd.h) \ + include/linux/timerqueue.h \ + include/linux/seccomp.h \ + $(wildcard include/config/seccomp.h) \ + $(wildcard include/config/have/arch/seccomp/filter.h) \ + $(wildcard include/config/seccomp/filter.h) \ + $(wildcard include/config/checkpoint/restore.h) \ + include/uapi/linux/seccomp.h \ + arch/x86/include/asm/seccomp.h \ + arch/x86/include/asm/unistd.h \ + $(wildcard include/config/x86/x32/abi.h) \ + arch/x86/include/uapi/asm/unistd.h \ + arch/x86/include/generated/uapi/asm/unistd_64.h \ + arch/x86/include/generated/asm/unistd_64_x32.h \ + arch/x86/include/asm/ia32_unistd.h \ + arch/x86/include/generated/asm/unistd_32_ia32.h \ + include/asm-generic/seccomp.h \ + include/uapi/linux/unistd.h \ + include/linux/resource.h \ + include/uapi/linux/resource.h \ + arch/x86/include/uapi/asm/resource.h \ + include/asm-generic/resource.h \ + include/uapi/asm-generic/resource.h \ + include/linux/latencytop.h \ + include/linux/sched/prio.h \ + include/linux/signal_types.h \ + $(wildcard include/config/old/sigaction.h) \ + include/uapi/linux/signal.h \ + arch/x86/include/asm/signal.h \ + arch/x86/include/uapi/asm/signal.h \ + include/uapi/asm-generic/signal-defs.h \ + arch/x86/include/uapi/asm/siginfo.h \ + include/uapi/asm-generic/siginfo.h \ + include/linux/task_io_accounting.h \ + $(wildcard include/config/task/io/accounting.h) \ + arch/x86/include/asm/uaccess.h \ + $(wildcard include/config/x86/intel/usercopy.h) \ + arch/x86/include/asm/smap.h \ + $(wildcard include/config/x86/smap.h) \ + arch/x86/include/asm/extable.h \ + arch/x86/include/asm/uaccess_64.h \ + arch/x86/include/asm/checksum.h \ + arch/x86/include/asm/checksum_64.h \ + include/linux/dma-mapping.h \ + $(wildcard include/config/have/generic/dma/coherent.h) \ + $(wildcard include/config/has/dma.h) \ + $(wildcard include/config/arch/has/dma/set/coherent/mask.h) \ + $(wildcard include/config/need/dma/map/state.h) \ + $(wildcard include/config/dma/api/debug.h) \ + include/linux/sizes.h \ + include/linux/device.h \ + $(wildcard include/config/debug/devres.h) \ + $(wildcard include/config/generic/msi/irq/domain.h) \ + $(wildcard include/config/pinctrl.h) \ + $(wildcard include/config/generic/msi/irq.h) \ + $(wildcard include/config/dma/cma.h) \ + $(wildcard include/config/of.h) \ + $(wildcard include/config/devtmpfs.h) \ + $(wildcard include/config/sysfs/deprecated.h) \ + include/linux/ioport.h \ + include/linux/kobject.h \ + $(wildcard include/config/uevent/helper.h) \ + $(wildcard include/config/debug/kobject/release.h) \ + include/linux/sysfs.h \ + include/linux/kernfs.h \ + $(wildcard include/config/kernfs.h) \ + include/linux/kobject_ns.h \ + include/linux/kref.h \ + include/linux/klist.h \ + include/linux/pinctrl/devinfo.h \ + $(wildcard include/config/pm.h) \ + include/linux/pinctrl/consumer.h \ + include/linux/seq_file.h \ + include/linux/cred.h \ + $(wildcard include/config/debug/credentials.h) \ + $(wildcard include/config/keys.h) \ + include/linux/key.h \ + include/linux/assoc_array.h \ + $(wildcard include/config/associative/array.h) \ + include/linux/selinux.h \ + $(wildcard include/config/security/selinux.h) \ + include/linux/sched/user.h \ + $(wildcard include/config/fanotify.h) \ + $(wildcard include/config/posix/mqueue.h) \ + $(wildcard include/config/bpf/syscall.h) \ + $(wildcard include/config/net.h) \ + include/linux/pinctrl/pinctrl-state.h \ + include/linux/pm.h \ + $(wildcard include/config/vt/console/sleep.h) \ + $(wildcard include/config/pm/clk.h) \ + $(wildcard include/config/pm/generic/domains.h) \ + include/linux/ratelimit.h \ + arch/x86/include/asm/device.h \ + $(wildcard include/config/intel/iommu.h) \ + $(wildcard include/config/amd/iommu.h) \ + $(wildcard include/config/x86/dev/dma/ops.h) \ + $(wildcard include/config/pci/domains.h) \ + include/linux/pm_wakeup.h \ + include/linux/dma-debug.h \ + include/linux/dma-direction.h \ + include/linux/scatterlist.h \ + $(wildcard include/config/debug/sg.h) \ + $(wildcard include/config/need/sg/dma/length.h) \ + $(wildcard include/config/sgl/alloc.h) \ + $(wildcard include/config/arch/has/sg/chain.h) \ + $(wildcard include/config/sg/pool.h) \ + include/linux/mm.h \ + $(wildcard include/config/have/arch/mmap/rnd/bits.h) \ + $(wildcard include/config/have/arch/mmap/rnd/compat/bits.h) \ + $(wildcard include/config/arch/uses/high/vma/flags.h) \ + $(wildcard include/config/ppc.h) \ + $(wildcard include/config/parisc.h) \ + $(wildcard include/config/metag.h) \ + $(wildcard include/config/ia64.h) \ + $(wildcard include/config/stack/growsup.h) \ + $(wildcard include/config/device/private.h) \ + $(wildcard include/config/device/public.h) \ + $(wildcard include/config/shmem.h) \ + $(wildcard include/config/have/memblock.h) \ + $(wildcard include/config/debug/vm/rb.h) \ + $(wildcard include/config/page/poisoning.h) \ + $(wildcard include/config/debug/pagealloc.h) \ + $(wildcard include/config/hibernation.h) \ + $(wildcard include/config/hugetlbfs.h) \ + include/linux/percpu-refcount.h \ + include/linux/page_ext.h \ + $(wildcard include/config/idle/page/tracking.h) \ + include/linux/stacktrace.h \ + $(wildcard include/config/stacktrace.h) \ + $(wildcard include/config/user/stacktrace/support.h) \ + include/linux/stackdepot.h \ + include/linux/page_ref.h \ + $(wildcard include/config/debug/page/ref.h) \ + include/linux/page-flags.h \ + $(wildcard include/config/arch/uses/pg/uncached.h) \ + $(wildcard include/config/memory/failure.h) \ + $(wildcard include/config/swap.h) \ + $(wildcard include/config/thp/swap.h) \ + $(wildcard include/config/ksm.h) \ + include/linux/memremap.h \ + arch/x86/include/asm/pgtable.h \ + $(wildcard include/config/debug/wx.h) \ + $(wildcard include/config/have/arch/transparent/hugepage/pud.h) \ + $(wildcard include/config/have/arch/soft/dirty.h) \ + $(wildcard include/config/arch/enable/thp/migration.h) \ + arch/x86/include/asm/pgtable_64.h \ + arch/x86/include/asm/pgtable-invert.h \ + include/asm-generic/pgtable.h \ + $(wildcard include/config/have/arch/huge/vmap.h) \ + $(wildcard include/config/x86/espfix64.h) \ + include/linux/huge_mm.h \ + include/linux/sched/coredump.h \ + $(wildcard include/config/core/dump/default/elf/headers.h) \ + include/linux/vmstat.h \ + $(wildcard include/config/vm/event/counters.h) \ + $(wildcard include/config/debug/tlbflush.h) \ + $(wildcard include/config/debug/vm/vmacache.h) \ + include/linux/vm_event_item.h \ + $(wildcard include/config/memory/balloon.h) \ + $(wildcard include/config/balloon/compaction.h) \ + arch/x86/include/asm/dma-mapping.h \ + $(wildcard include/config/isa.h) \ + $(wildcard include/config/x86/dma/remap.h) \ + arch/x86/include/asm/swiotlb.h \ + $(wildcard include/config/swiotlb.h) \ + include/linux/swiotlb.h \ + include/linux/dma-contiguous.h \ + include/linux/netdev_features.h \ + include/linux/sched/clock.h \ + $(wildcard include/config/have/unstable/sched/clock.h) \ + $(wildcard include/config/irq/time/accounting.h) \ + include/linux/splice.h \ + include/linux/pipe_fs_i.h \ + include/uapi/linux/if_packet.h \ + include/linux/seq_file_net.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + +/data/libkernelsepol/libsepol/src/inet_ntop.o: $(deps_/data/libkernelsepol/libsepol/src/inet_ntop.o) + +$(deps_/data/libkernelsepol/libsepol/src/inet_ntop.o): diff --git a/kernel/libsepol/src/.link.o.cmd b/kernel/libsepol/src/.link.o.cmd new file mode 100644 index 00000000..e040555f --- /dev/null +++ b/kernel/libsepol/src/.link.o.cmd @@ -0,0 +1,609 @@ +cmd_/data/libkernelsepol/libsepol/src/link.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.link.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"link"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_link.o /data/libkernelsepol/libsepol/src/link.c + +source_/data/libkernelsepol/libsepol/src/link.o := /data/libkernelsepol/libsepol/src/link.c + +deps_/data/libkernelsepol/libsepol/src/link.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avrule_block.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/link.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/util.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + +/data/libkernelsepol/libsepol/src/link.o: $(deps_/data/libkernelsepol/libsepol/src/link.o) + +$(deps_/data/libkernelsepol/libsepol/src/link.o): diff --git a/kernel/libsepol/src/.mls.o.cmd b/kernel/libsepol/src/.mls.o.cmd new file mode 100644 index 00000000..37b5b1ee --- /dev/null +++ b/kernel/libsepol/src/.mls.o.cmd @@ -0,0 +1,610 @@ +cmd_/data/libkernelsepol/libsepol/src/mls.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.mls.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"mls"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_mls.o /data/libkernelsepol/libsepol/src/mls.c + +source_/data/libkernelsepol/libsepol/src/mls.o := /data/libkernelsepol/libsepol/src/mls.c + +deps_/data/libkernelsepol/libsepol/src/mls.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/services.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/src/mls.h \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + +/data/libkernelsepol/libsepol/src/mls.o: $(deps_/data/libkernelsepol/libsepol/src/mls.o) + +$(deps_/data/libkernelsepol/libsepol/src/mls.o): diff --git a/kernel/libsepol/src/.module.o.cmd b/kernel/libsepol/src/.module.o.cmd new file mode 100644 index 00000000..1ca6deeb --- /dev/null +++ b/kernel/libsepol/src/.module.o.cmd @@ -0,0 +1,613 @@ +cmd_/data/libkernelsepol/libsepol/src/module.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.module.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"module"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_module.o /data/libkernelsepol/libsepol/src/module.c + +source_/data/libkernelsepol/libsepol/src/module.o := /data/libkernelsepol/libsepol/src/module.c + +deps_/data/libkernelsepol/libsepol/src/module.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/src/module_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/module.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/link.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/module.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + include/uapi/linux/limits.h \ + +/data/libkernelsepol/libsepol/src/module.o: $(deps_/data/libkernelsepol/libsepol/src/module.o) + +$(deps_/data/libkernelsepol/libsepol/src/module.o): diff --git a/kernel/libsepol/src/.node_record.o.cmd b/kernel/libsepol/src/.node_record.o.cmd new file mode 100644 index 00000000..e59b27eb --- /dev/null +++ b/kernel/libsepol/src/.node_record.o.cmd @@ -0,0 +1,1028 @@ +cmd_/data/libkernelsepol/libsepol/src/node_record.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.node_record.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"node_record"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_node_record.o /data/libkernelsepol/libsepol/src/node_record.c + +source_/data/libkernelsepol/libsepol/src/node_record.o := /data/libkernelsepol/libsepol/src/node_record.c + +deps_/data/libkernelsepol/libsepol/src/node_record.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + include/linux/in.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + include/uapi/linux/in.h \ + include/uapi/linux/libc-compat.h \ + $(wildcard include/config/data.h) \ + include/linux/socket.h \ + $(wildcard include/config/proc/fs.h) \ + $(wildcard include/config/compat.h) \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/restart_block.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + $(wildcard include/config/sparsemem.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + include/linux/inet.h \ + include/net/net_namespace.h \ + $(wildcard include/config/nf/conntrack.h) \ + $(wildcard include/config/sysctl.h) \ + $(wildcard include/config/ipv6.h) \ + $(wildcard include/config/ieee802154/6lowpan.h) \ + $(wildcard include/config/ip/sctp.h) \ + $(wildcard include/config/ip/dccp.h) \ + $(wildcard include/config/netfilter.h) \ + $(wildcard include/config/nf/tables.h) \ + $(wildcard include/config/nf/defrag/ipv6.h) \ + $(wildcard include/config/netfilter/netlink/acct.h) \ + $(wildcard include/config/nf/ct/netlink/timeout.h) \ + $(wildcard include/config/wext/core.h) \ + $(wildcard include/config/xfrm.h) \ + $(wildcard include/config/ip/vs.h) \ + $(wildcard include/config/mpls.h) \ + $(wildcard include/config/can.h) \ + $(wildcard include/config/net/ns.h) \ + include/linux/refcount.h \ + $(wildcard include/config/refcount/full.h) \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + include/linux/spinlock_types.h \ + $(wildcard include/config/debug/spinlock.h) \ + include/linux/lockdep.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/preempt.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + arch/x86/include/asm/preempt.h \ + include/linux/bottom_half.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + arch/x86/include/asm/refcount.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/seqlock.h \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/sysctl.h \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/rbtree.h \ + include/linux/uidgid.h \ + $(wildcard include/config/multiuser.h) \ + $(wildcard include/config/user/ns.h) \ + include/linux/highuid.h \ + include/uapi/linux/sysctl.h \ + include/net/flow.h \ + include/linux/in6.h \ + include/uapi/linux/in6.h \ + include/net/flow_dissector.h \ + include/linux/siphash.h \ + $(wildcard include/config/have/efficient/unaligned/access.h) \ + include/uapi/linux/if_ether.h \ + include/net/netns/core.h \ + include/net/netns/mib.h \ + $(wildcard include/config/xfrm/statistics.h) \ + include/net/snmp.h \ + include/uapi/linux/snmp.h \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/numa/emu.h) \ + include/linux/nodemask.h \ + $(wildcard include/config/highmem.h) \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/u64_stats_sync.h \ + include/net/netns/unix.h \ + include/net/netns/packet.h \ + include/linux/rculist.h \ + include/net/netns/ipv4.h \ + $(wildcard include/config/ip/multiple/tables.h) \ + $(wildcard include/config/ip/route/classid.h) \ + $(wildcard include/config/security.h) \ + $(wildcard include/config/net/l3/master/dev.h) \ + $(wildcard include/config/ip/mroute.h) \ + $(wildcard include/config/ip/mroute/multiple/tables.h) \ + $(wildcard include/config/ip/route/multipath.h) \ + include/net/inet_frag.h \ + include/linux/rhashtable.h \ + include/linux/jhash.h \ + include/linux/unaligned/packed_struct.h \ + include/linux/list_nulls.h \ + include/net/netns/ipv6.h \ + $(wildcard include/config/ipv6/multiple/tables.h) \ + $(wildcard include/config/ipv6/mroute.h) \ + $(wildcard include/config/ipv6/mroute/multiple/tables.h) \ + include/net/dst_ops.h \ + include/linux/percpu_counter.h \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/gfp.h \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/net/netns/ieee802154_6lowpan.h \ + include/net/netns/sctp.h \ + include/net/netns/dccp.h \ + include/net/netns/netfilter.h \ + $(wildcard include/config/nf/defrag/ipv4.h) \ + include/linux/netfilter_defs.h \ + include/uapi/linux/netfilter.h \ + include/net/netns/x_tables.h \ + $(wildcard include/config/bridge/nf/ebtables.h) \ + include/net/netns/conntrack.h \ + $(wildcard include/config/nf/ct/proto/dccp.h) \ + $(wildcard include/config/nf/ct/proto/sctp.h) \ + $(wildcard include/config/nf/conntrack/events.h) \ + $(wildcard include/config/nf/conntrack/labels.h) \ + include/linux/netfilter/nf_conntrack_tcp.h \ + include/uapi/linux/netfilter/nf_conntrack_tcp.h \ + include/linux/netfilter/nf_conntrack_dccp.h \ + include/uapi/linux/netfilter/nf_conntrack_tuple_common.h \ + include/linux/netfilter/nf_conntrack_common.h \ + include/uapi/linux/netfilter/nf_conntrack_common.h \ + include/linux/netfilter/nf_conntrack_sctp.h \ + include/uapi/linux/netfilter/nf_conntrack_sctp.h \ + include/net/netns/nftables.h \ + include/net/netns/xfrm.h \ + include/uapi/linux/xfrm.h \ + include/net/netns/mpls.h \ + include/net/netns/can.h \ + include/linux/ns_common.h \ + include/linux/idr.h \ + include/linux/radix-tree.h \ + $(wildcard include/config/radix/tree/multiorder.h) \ + include/linux/skbuff.h \ + $(wildcard include/config/bridge/netfilter.h) \ + $(wildcard include/config/ipv6/ndisc/nodetype.h) \ + $(wildcard include/config/net/switchdev.h) \ + $(wildcard include/config/net/cls/act.h) \ + $(wildcard include/config/net/sched.h) \ + $(wildcard include/config/net/rx/busy/poll.h) \ + $(wildcard include/config/xps.h) \ + $(wildcard include/config/network/secmark.h) \ + $(wildcard include/config/network/phy/timestamping.h) \ + $(wildcard include/config/netfilter/xt/target/trace.h) \ + include/linux/net.h \ + include/linux/random.h \ + $(wildcard include/config/gcc/plugin/latent/entropy.h) \ + $(wildcard include/config/arch/random.h) \ + include/linux/once.h \ + include/uapi/linux/random.h \ + include/linux/irqnr.h \ + include/uapi/linux/irqnr.h \ + include/linux/prandom.h \ + arch/x86/include/asm/archrandom.h \ + include/linux/fcntl.h \ + include/uapi/linux/fcntl.h \ + arch/x86/include/uapi/asm/fcntl.h \ + include/uapi/asm-generic/fcntl.h \ + include/linux/fs.h \ + $(wildcard include/config/fs/posix/acl.h) \ + $(wildcard include/config/cgroup/writeback.h) \ + $(wildcard include/config/ima.h) \ + $(wildcard include/config/fsnotify.h) \ + $(wildcard include/config/fs/encryption.h) \ + $(wildcard include/config/epoll.h) \ + $(wildcard include/config/file/locking.h) \ + $(wildcard include/config/quota.h) \ + $(wildcard include/config/blk/dev/loop.h) \ + $(wildcard include/config/fs/dax.h) \ + $(wildcard include/config/block.h) \ + $(wildcard include/config/mandatory/file/locking.h) \ + $(wildcard include/config/migration.h) \ + include/linux/wait_bit.h \ + include/linux/kdev_t.h \ + include/uapi/linux/kdev_t.h \ + include/linux/dcache.h \ + include/linux/rculist_bl.h \ + include/linux/list_bl.h \ + include/linux/bit_spinlock.h \ + include/linux/lockref.h \ + $(wildcard include/config/arch/use/cmpxchg/lockref.h) \ + include/linux/stringhash.h \ + $(wildcard include/config/dcache/word/access.h) \ + include/linux/hash.h \ + $(wildcard include/config/have/arch/hash.h) \ + include/linux/path.h \ + include/linux/stat.h \ + arch/x86/include/uapi/asm/stat.h \ + include/uapi/linux/stat.h \ + include/linux/list_lru.h \ + $(wildcard include/config/slob.h) \ + include/linux/shrinker.h \ + include/linux/pid.h \ + include/linux/mm_types.h \ + $(wildcard include/config/have/cmpxchg/double.h) \ + $(wildcard include/config/have/aligned/struct/page.h) \ + $(wildcard include/config/userfaultfd.h) \ + $(wildcard include/config/have/arch/compat/mmap/bases.h) \ + $(wildcard include/config/membarrier.h) \ + $(wildcard include/config/aio.h) \ + $(wildcard include/config/mmu/notifier.h) \ + $(wildcard include/config/arch/want/batched/unmap/tlb/flush.h) \ + $(wildcard include/config/hmm.h) \ + include/linux/mm_types_task.h \ + $(wildcard include/config/split/ptlock/cpus.h) \ + $(wildcard include/config/arch/enable/split/pmd/ptlock.h) \ + arch/x86/include/asm/tlbbatch.h \ + include/linux/auxvec.h \ + include/uapi/linux/auxvec.h \ + arch/x86/include/uapi/asm/auxvec.h \ + include/linux/uprobes.h \ + $(wildcard include/config/uprobes.h) \ + arch/x86/include/asm/uprobes.h \ + include/linux/capability.h \ + include/uapi/linux/capability.h \ + include/linux/semaphore.h \ + include/uapi/linux/fiemap.h \ + include/linux/migrate_mode.h \ + include/linux/percpu-rwsem.h \ + include/linux/rcuwait.h \ + include/linux/rcu_sync.h \ + include/linux/delayed_call.h \ + include/linux/uuid.h \ + include/uapi/linux/uuid.h \ + include/linux/errseq.h \ + include/uapi/linux/fs.h \ + include/uapi/linux/limits.h \ + include/linux/quota.h \ + $(wildcard include/config/quota/netlink/interface.h) \ + include/uapi/linux/dqblk_xfs.h \ + include/linux/dqblk_v1.h \ + include/linux/dqblk_v2.h \ + include/linux/dqblk_qtree.h \ + include/linux/projid.h \ + include/uapi/linux/quota.h \ + include/linux/nfs_fs_i.h \ + include/uapi/linux/net.h \ + include/linux/textsearch.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/net/checksum.h \ + include/linux/uaccess.h \ + include/linux/sched.h \ + $(wildcard include/config/virt/cpu/accounting/native.h) \ + $(wildcard include/config/sched/info.h) \ + $(wildcard include/config/schedstats.h) \ + $(wildcard include/config/fair/group/sched.h) \ + $(wildcard include/config/rt/group/sched.h) \ + $(wildcard include/config/cgroup/sched.h) \ + $(wildcard include/config/blk/dev/io/trace.h) \ + $(wildcard include/config/compat/brk.h) \ + $(wildcard include/config/cgroups.h) \ + $(wildcard include/config/arch/has/scaled/cputime.h) \ + $(wildcard include/config/virt/cpu/accounting/gen.h) \ + $(wildcard include/config/posix/timers.h) \ + $(wildcard include/config/sysvipc.h) \ + $(wildcard include/config/detect/hung/task.h) \ + $(wildcard include/config/auditsyscall.h) \ + $(wildcard include/config/rt/mutexes.h) \ + $(wildcard include/config/ubsan.h) \ + $(wildcard include/config/task/xacct.h) \ + $(wildcard include/config/cpusets.h) \ + $(wildcard include/config/intel/rdt.h) \ + $(wildcard include/config/futex.h) \ + $(wildcard include/config/perf/events.h) \ + $(wildcard include/config/task/delay/acct.h) \ + $(wildcard include/config/fault/injection.h) \ + $(wildcard include/config/latencytop.h) \ + $(wildcard include/config/function/graph/tracer.h) \ + $(wildcard include/config/kcov.h) \ + $(wildcard include/config/bcache.h) \ + $(wildcard include/config/vmap/stack.h) \ + $(wildcard include/config/livepatch.h) \ + include/uapi/linux/sched.h \ + include/linux/sem.h \ + include/uapi/linux/sem.h \ + include/linux/ipc.h \ + include/uapi/linux/ipc.h \ + arch/x86/include/uapi/asm/ipcbuf.h \ + include/uapi/asm-generic/ipcbuf.h \ + arch/x86/include/uapi/asm/sembuf.h \ + include/linux/shm.h \ + include/uapi/linux/shm.h \ + include/uapi/asm-generic/hugetlb_encode.h \ + arch/x86/include/uapi/asm/shmbuf.h \ + include/uapi/asm-generic/shmbuf.h \ + arch/x86/include/asm/shmparam.h \ + include/linux/kcov.h \ + include/uapi/linux/kcov.h \ + include/linux/plist.h \ + $(wildcard include/config/debug/pi/list.h) \ + include/linux/hrtimer.h \ + $(wildcard include/config/high/res/timers.h) \ + $(wildcard include/config/time/low/res.h) \ + $(wildcard include/config/timerfd.h) \ + include/linux/timerqueue.h \ + include/linux/seccomp.h \ + $(wildcard include/config/seccomp.h) \ + $(wildcard include/config/have/arch/seccomp/filter.h) \ + $(wildcard include/config/seccomp/filter.h) \ + $(wildcard include/config/checkpoint/restore.h) \ + include/uapi/linux/seccomp.h \ + arch/x86/include/asm/seccomp.h \ + arch/x86/include/asm/unistd.h \ + $(wildcard include/config/x86/x32/abi.h) \ + arch/x86/include/uapi/asm/unistd.h \ + arch/x86/include/generated/uapi/asm/unistd_64.h \ + arch/x86/include/generated/asm/unistd_64_x32.h \ + arch/x86/include/asm/ia32_unistd.h \ + arch/x86/include/generated/asm/unistd_32_ia32.h \ + include/asm-generic/seccomp.h \ + include/uapi/linux/unistd.h \ + include/linux/resource.h \ + include/uapi/linux/resource.h \ + arch/x86/include/uapi/asm/resource.h \ + include/asm-generic/resource.h \ + include/uapi/asm-generic/resource.h \ + include/linux/latencytop.h \ + include/linux/sched/prio.h \ + include/linux/signal_types.h \ + $(wildcard include/config/old/sigaction.h) \ + include/uapi/linux/signal.h \ + arch/x86/include/asm/signal.h \ + arch/x86/include/uapi/asm/signal.h \ + include/uapi/asm-generic/signal-defs.h \ + arch/x86/include/uapi/asm/siginfo.h \ + include/uapi/asm-generic/siginfo.h \ + include/linux/task_io_accounting.h \ + $(wildcard include/config/task/io/accounting.h) \ + arch/x86/include/asm/uaccess.h \ + $(wildcard include/config/x86/intel/usercopy.h) \ + arch/x86/include/asm/smap.h \ + $(wildcard include/config/x86/smap.h) \ + arch/x86/include/asm/extable.h \ + arch/x86/include/asm/uaccess_64.h \ + arch/x86/include/asm/checksum.h \ + arch/x86/include/asm/checksum_64.h \ + include/linux/dma-mapping.h \ + $(wildcard include/config/have/generic/dma/coherent.h) \ + $(wildcard include/config/has/dma.h) \ + $(wildcard include/config/arch/has/dma/set/coherent/mask.h) \ + $(wildcard include/config/need/dma/map/state.h) \ + $(wildcard include/config/dma/api/debug.h) \ + include/linux/sizes.h \ + include/linux/device.h \ + $(wildcard include/config/debug/devres.h) \ + $(wildcard include/config/generic/msi/irq/domain.h) \ + $(wildcard include/config/pinctrl.h) \ + $(wildcard include/config/generic/msi/irq.h) \ + $(wildcard include/config/dma/cma.h) \ + $(wildcard include/config/of.h) \ + $(wildcard include/config/devtmpfs.h) \ + $(wildcard include/config/sysfs/deprecated.h) \ + include/linux/ioport.h \ + include/linux/kobject.h \ + $(wildcard include/config/uevent/helper.h) \ + $(wildcard include/config/debug/kobject/release.h) \ + include/linux/sysfs.h \ + include/linux/kernfs.h \ + $(wildcard include/config/kernfs.h) \ + include/linux/kobject_ns.h \ + include/linux/kref.h \ + include/linux/klist.h \ + include/linux/pinctrl/devinfo.h \ + $(wildcard include/config/pm.h) \ + include/linux/pinctrl/consumer.h \ + include/linux/seq_file.h \ + include/linux/cred.h \ + $(wildcard include/config/debug/credentials.h) \ + $(wildcard include/config/keys.h) \ + include/linux/key.h \ + include/linux/assoc_array.h \ + $(wildcard include/config/associative/array.h) \ + include/linux/selinux.h \ + $(wildcard include/config/security/selinux.h) \ + include/linux/sched/user.h \ + $(wildcard include/config/fanotify.h) \ + $(wildcard include/config/posix/mqueue.h) \ + $(wildcard include/config/bpf/syscall.h) \ + $(wildcard include/config/net.h) \ + include/linux/pinctrl/pinctrl-state.h \ + include/linux/pm.h \ + $(wildcard include/config/vt/console/sleep.h) \ + $(wildcard include/config/pm/clk.h) \ + $(wildcard include/config/pm/generic/domains.h) \ + include/linux/ratelimit.h \ + arch/x86/include/asm/device.h \ + $(wildcard include/config/intel/iommu.h) \ + $(wildcard include/config/amd/iommu.h) \ + $(wildcard include/config/x86/dev/dma/ops.h) \ + $(wildcard include/config/pci/domains.h) \ + include/linux/pm_wakeup.h \ + include/linux/dma-debug.h \ + include/linux/dma-direction.h \ + include/linux/scatterlist.h \ + $(wildcard include/config/debug/sg.h) \ + $(wildcard include/config/need/sg/dma/length.h) \ + $(wildcard include/config/sgl/alloc.h) \ + $(wildcard include/config/arch/has/sg/chain.h) \ + $(wildcard include/config/sg/pool.h) \ + include/linux/mm.h \ + $(wildcard include/config/have/arch/mmap/rnd/bits.h) \ + $(wildcard include/config/have/arch/mmap/rnd/compat/bits.h) \ + $(wildcard include/config/arch/uses/high/vma/flags.h) \ + $(wildcard include/config/ppc.h) \ + $(wildcard include/config/parisc.h) \ + $(wildcard include/config/metag.h) \ + $(wildcard include/config/ia64.h) \ + $(wildcard include/config/stack/growsup.h) \ + $(wildcard include/config/device/private.h) \ + $(wildcard include/config/device/public.h) \ + $(wildcard include/config/shmem.h) \ + $(wildcard include/config/have/memblock.h) \ + $(wildcard include/config/debug/vm/rb.h) \ + $(wildcard include/config/page/poisoning.h) \ + $(wildcard include/config/debug/pagealloc.h) \ + $(wildcard include/config/hibernation.h) \ + $(wildcard include/config/hugetlbfs.h) \ + include/linux/percpu-refcount.h \ + include/linux/page_ext.h \ + $(wildcard include/config/idle/page/tracking.h) \ + include/linux/stacktrace.h \ + $(wildcard include/config/stacktrace.h) \ + $(wildcard include/config/user/stacktrace/support.h) \ + include/linux/stackdepot.h \ + include/linux/page_ref.h \ + $(wildcard include/config/debug/page/ref.h) \ + include/linux/page-flags.h \ + $(wildcard include/config/arch/uses/pg/uncached.h) \ + $(wildcard include/config/memory/failure.h) \ + $(wildcard include/config/swap.h) \ + $(wildcard include/config/thp/swap.h) \ + $(wildcard include/config/ksm.h) \ + include/linux/memremap.h \ + arch/x86/include/asm/pgtable.h \ + $(wildcard include/config/debug/wx.h) \ + $(wildcard include/config/have/arch/transparent/hugepage/pud.h) \ + $(wildcard include/config/have/arch/soft/dirty.h) \ + $(wildcard include/config/arch/enable/thp/migration.h) \ + arch/x86/include/asm/pgtable_64.h \ + arch/x86/include/asm/pgtable-invert.h \ + include/asm-generic/pgtable.h \ + $(wildcard include/config/have/arch/huge/vmap.h) \ + $(wildcard include/config/x86/espfix64.h) \ + include/linux/huge_mm.h \ + include/linux/sched/coredump.h \ + $(wildcard include/config/core/dump/default/elf/headers.h) \ + include/linux/vmstat.h \ + $(wildcard include/config/vm/event/counters.h) \ + $(wildcard include/config/debug/tlbflush.h) \ + $(wildcard include/config/debug/vm/vmacache.h) \ + include/linux/vm_event_item.h \ + $(wildcard include/config/memory/balloon.h) \ + $(wildcard include/config/balloon/compaction.h) \ + arch/x86/include/asm/dma-mapping.h \ + $(wildcard include/config/isa.h) \ + $(wildcard include/config/x86/dma/remap.h) \ + arch/x86/include/asm/swiotlb.h \ + $(wildcard include/config/swiotlb.h) \ + include/linux/swiotlb.h \ + include/linux/dma-contiguous.h \ + include/linux/netdev_features.h \ + include/linux/sched/clock.h \ + $(wildcard include/config/have/unstable/sched/clock.h) \ + $(wildcard include/config/irq/time/accounting.h) \ + include/linux/splice.h \ + include/linux/pipe_fs_i.h \ + include/uapi/linux/if_packet.h \ + include/linux/seq_file_net.h \ + /data/libkernelsepol/libsepol/src/node_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/node_record.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/nodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + +/data/libkernelsepol/libsepol/src/node_record.o: $(deps_/data/libkernelsepol/libsepol/src/node_record.o) + +$(deps_/data/libkernelsepol/libsepol/src/node_record.o): diff --git a/kernel/libsepol/src/.nodes.o.cmd b/kernel/libsepol/src/.nodes.o.cmd new file mode 100644 index 00000000..af28386e --- /dev/null +++ b/kernel/libsepol/src/.nodes.o.cmd @@ -0,0 +1,1042 @@ +cmd_/data/libkernelsepol/libsepol/src/nodes.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.nodes.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"nodes"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_nodes.o /data/libkernelsepol/libsepol/src/nodes.c + +source_/data/libkernelsepol/libsepol/src/nodes.o := /data/libkernelsepol/libsepol/src/nodes.c + +deps_/data/libkernelsepol/libsepol/src/nodes.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/in.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + include/uapi/linux/in.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + include/uapi/linux/libc-compat.h \ + $(wildcard include/config/data.h) \ + include/linux/socket.h \ + $(wildcard include/config/proc/fs.h) \ + $(wildcard include/config/compat.h) \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/linux/linkage.h \ + include/linux/stringify.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/64.h) \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + $(wildcard include/config/kasan.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + $(wildcard include/config/jump/label.h) \ + include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h \ + include/linux/build_bug.h \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/restart_block.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + $(wildcard include/config/sparsemem.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + include/linux/inet.h \ + include/net/net_namespace.h \ + $(wildcard include/config/nf/conntrack.h) \ + $(wildcard include/config/sysctl.h) \ + $(wildcard include/config/ipv6.h) \ + $(wildcard include/config/ieee802154/6lowpan.h) \ + $(wildcard include/config/ip/sctp.h) \ + $(wildcard include/config/ip/dccp.h) \ + $(wildcard include/config/netfilter.h) \ + $(wildcard include/config/nf/tables.h) \ + $(wildcard include/config/nf/defrag/ipv6.h) \ + $(wildcard include/config/netfilter/netlink/acct.h) \ + $(wildcard include/config/nf/ct/netlink/timeout.h) \ + $(wildcard include/config/wext/core.h) \ + $(wildcard include/config/xfrm.h) \ + $(wildcard include/config/ip/vs.h) \ + $(wildcard include/config/mpls.h) \ + $(wildcard include/config/can.h) \ + $(wildcard include/config/net/ns.h) \ + include/linux/refcount.h \ + $(wildcard include/config/refcount/full.h) \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + include/linux/spinlock_types.h \ + $(wildcard include/config/debug/spinlock.h) \ + include/linux/lockdep.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/preempt.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + arch/x86/include/asm/preempt.h \ + include/linux/bottom_half.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + arch/x86/include/asm/refcount.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/seqlock.h \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/sysctl.h \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/rbtree.h \ + include/linux/uidgid.h \ + $(wildcard include/config/multiuser.h) \ + $(wildcard include/config/user/ns.h) \ + include/linux/highuid.h \ + include/uapi/linux/sysctl.h \ + include/net/flow.h \ + include/linux/in6.h \ + include/uapi/linux/in6.h \ + include/net/flow_dissector.h \ + include/linux/siphash.h \ + $(wildcard include/config/have/efficient/unaligned/access.h) \ + include/uapi/linux/if_ether.h \ + include/net/netns/core.h \ + include/net/netns/mib.h \ + $(wildcard include/config/xfrm/statistics.h) \ + include/net/snmp.h \ + include/uapi/linux/snmp.h \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/numa/emu.h) \ + include/linux/nodemask.h \ + $(wildcard include/config/highmem.h) \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/u64_stats_sync.h \ + include/net/netns/unix.h \ + include/net/netns/packet.h \ + include/linux/rculist.h \ + include/net/netns/ipv4.h \ + $(wildcard include/config/ip/multiple/tables.h) \ + $(wildcard include/config/ip/route/classid.h) \ + $(wildcard include/config/security.h) \ + $(wildcard include/config/net/l3/master/dev.h) \ + $(wildcard include/config/ip/mroute.h) \ + $(wildcard include/config/ip/mroute/multiple/tables.h) \ + $(wildcard include/config/ip/route/multipath.h) \ + include/net/inet_frag.h \ + include/linux/rhashtable.h \ + include/linux/jhash.h \ + include/linux/unaligned/packed_struct.h \ + include/linux/list_nulls.h \ + include/net/netns/ipv6.h \ + $(wildcard include/config/ipv6/multiple/tables.h) \ + $(wildcard include/config/ipv6/mroute.h) \ + $(wildcard include/config/ipv6/mroute/multiple/tables.h) \ + include/net/dst_ops.h \ + include/linux/percpu_counter.h \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/gfp.h \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/net/netns/ieee802154_6lowpan.h \ + include/net/netns/sctp.h \ + include/net/netns/dccp.h \ + include/net/netns/netfilter.h \ + $(wildcard include/config/nf/defrag/ipv4.h) \ + include/linux/netfilter_defs.h \ + include/uapi/linux/netfilter.h \ + include/net/netns/x_tables.h \ + $(wildcard include/config/bridge/nf/ebtables.h) \ + include/net/netns/conntrack.h \ + $(wildcard include/config/nf/ct/proto/dccp.h) \ + $(wildcard include/config/nf/ct/proto/sctp.h) \ + $(wildcard include/config/nf/conntrack/events.h) \ + $(wildcard include/config/nf/conntrack/labels.h) \ + include/linux/netfilter/nf_conntrack_tcp.h \ + include/uapi/linux/netfilter/nf_conntrack_tcp.h \ + include/linux/netfilter/nf_conntrack_dccp.h \ + include/uapi/linux/netfilter/nf_conntrack_tuple_common.h \ + include/linux/netfilter/nf_conntrack_common.h \ + include/uapi/linux/netfilter/nf_conntrack_common.h \ + include/linux/netfilter/nf_conntrack_sctp.h \ + include/uapi/linux/netfilter/nf_conntrack_sctp.h \ + include/net/netns/nftables.h \ + include/net/netns/xfrm.h \ + include/uapi/linux/xfrm.h \ + include/net/netns/mpls.h \ + include/net/netns/can.h \ + include/linux/ns_common.h \ + include/linux/idr.h \ + include/linux/radix-tree.h \ + $(wildcard include/config/radix/tree/multiorder.h) \ + include/linux/skbuff.h \ + $(wildcard include/config/bridge/netfilter.h) \ + $(wildcard include/config/ipv6/ndisc/nodetype.h) \ + $(wildcard include/config/net/switchdev.h) \ + $(wildcard include/config/net/cls/act.h) \ + $(wildcard include/config/net/sched.h) \ + $(wildcard include/config/net/rx/busy/poll.h) \ + $(wildcard include/config/xps.h) \ + $(wildcard include/config/network/secmark.h) \ + $(wildcard include/config/network/phy/timestamping.h) \ + $(wildcard include/config/netfilter/xt/target/trace.h) \ + include/linux/net.h \ + include/linux/random.h \ + $(wildcard include/config/gcc/plugin/latent/entropy.h) \ + $(wildcard include/config/arch/random.h) \ + include/linux/once.h \ + include/uapi/linux/random.h \ + include/linux/irqnr.h \ + include/uapi/linux/irqnr.h \ + include/linux/prandom.h \ + arch/x86/include/asm/archrandom.h \ + include/linux/fcntl.h \ + include/uapi/linux/fcntl.h \ + arch/x86/include/uapi/asm/fcntl.h \ + include/uapi/asm-generic/fcntl.h \ + include/linux/fs.h \ + $(wildcard include/config/fs/posix/acl.h) \ + $(wildcard include/config/cgroup/writeback.h) \ + $(wildcard include/config/ima.h) \ + $(wildcard include/config/fsnotify.h) \ + $(wildcard include/config/fs/encryption.h) \ + $(wildcard include/config/epoll.h) \ + $(wildcard include/config/file/locking.h) \ + $(wildcard include/config/quota.h) \ + $(wildcard include/config/blk/dev/loop.h) \ + $(wildcard include/config/fs/dax.h) \ + $(wildcard include/config/block.h) \ + $(wildcard include/config/mandatory/file/locking.h) \ + $(wildcard include/config/migration.h) \ + include/linux/wait_bit.h \ + include/linux/kdev_t.h \ + include/uapi/linux/kdev_t.h \ + include/linux/dcache.h \ + include/linux/rculist_bl.h \ + include/linux/list_bl.h \ + include/linux/bit_spinlock.h \ + include/linux/lockref.h \ + $(wildcard include/config/arch/use/cmpxchg/lockref.h) \ + include/linux/stringhash.h \ + $(wildcard include/config/dcache/word/access.h) \ + include/linux/hash.h \ + $(wildcard include/config/have/arch/hash.h) \ + include/linux/path.h \ + include/linux/stat.h \ + arch/x86/include/uapi/asm/stat.h \ + include/uapi/linux/stat.h \ + include/linux/list_lru.h \ + $(wildcard include/config/slob.h) \ + include/linux/shrinker.h \ + include/linux/pid.h \ + include/linux/mm_types.h \ + $(wildcard include/config/have/cmpxchg/double.h) \ + $(wildcard include/config/have/aligned/struct/page.h) \ + $(wildcard include/config/userfaultfd.h) \ + $(wildcard include/config/have/arch/compat/mmap/bases.h) \ + $(wildcard include/config/membarrier.h) \ + $(wildcard include/config/aio.h) \ + $(wildcard include/config/mmu/notifier.h) \ + $(wildcard include/config/arch/want/batched/unmap/tlb/flush.h) \ + $(wildcard include/config/hmm.h) \ + include/linux/mm_types_task.h \ + $(wildcard include/config/split/ptlock/cpus.h) \ + $(wildcard include/config/arch/enable/split/pmd/ptlock.h) \ + arch/x86/include/asm/tlbbatch.h \ + include/linux/auxvec.h \ + include/uapi/linux/auxvec.h \ + arch/x86/include/uapi/asm/auxvec.h \ + include/linux/uprobes.h \ + $(wildcard include/config/uprobes.h) \ + arch/x86/include/asm/uprobes.h \ + include/linux/capability.h \ + include/uapi/linux/capability.h \ + include/linux/semaphore.h \ + include/uapi/linux/fiemap.h \ + include/linux/migrate_mode.h \ + include/linux/percpu-rwsem.h \ + include/linux/rcuwait.h \ + include/linux/rcu_sync.h \ + include/linux/delayed_call.h \ + include/linux/uuid.h \ + include/uapi/linux/uuid.h \ + include/linux/errseq.h \ + include/uapi/linux/fs.h \ + include/uapi/linux/limits.h \ + include/linux/quota.h \ + $(wildcard include/config/quota/netlink/interface.h) \ + include/uapi/linux/dqblk_xfs.h \ + include/linux/dqblk_v1.h \ + include/linux/dqblk_v2.h \ + include/linux/dqblk_qtree.h \ + include/linux/projid.h \ + include/uapi/linux/quota.h \ + include/linux/nfs_fs_i.h \ + include/uapi/linux/net.h \ + include/linux/textsearch.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/net/checksum.h \ + include/linux/uaccess.h \ + include/linux/sched.h \ + $(wildcard include/config/virt/cpu/accounting/native.h) \ + $(wildcard include/config/sched/info.h) \ + $(wildcard include/config/schedstats.h) \ + $(wildcard include/config/fair/group/sched.h) \ + $(wildcard include/config/rt/group/sched.h) \ + $(wildcard include/config/cgroup/sched.h) \ + $(wildcard include/config/blk/dev/io/trace.h) \ + $(wildcard include/config/compat/brk.h) \ + $(wildcard include/config/cgroups.h) \ + $(wildcard include/config/arch/has/scaled/cputime.h) \ + $(wildcard include/config/virt/cpu/accounting/gen.h) \ + $(wildcard include/config/posix/timers.h) \ + $(wildcard include/config/sysvipc.h) \ + $(wildcard include/config/detect/hung/task.h) \ + $(wildcard include/config/auditsyscall.h) \ + $(wildcard include/config/rt/mutexes.h) \ + $(wildcard include/config/ubsan.h) \ + $(wildcard include/config/task/xacct.h) \ + $(wildcard include/config/cpusets.h) \ + $(wildcard include/config/intel/rdt.h) \ + $(wildcard include/config/futex.h) \ + $(wildcard include/config/perf/events.h) \ + $(wildcard include/config/task/delay/acct.h) \ + $(wildcard include/config/fault/injection.h) \ + $(wildcard include/config/latencytop.h) \ + $(wildcard include/config/function/graph/tracer.h) \ + $(wildcard include/config/kcov.h) \ + $(wildcard include/config/bcache.h) \ + $(wildcard include/config/vmap/stack.h) \ + $(wildcard include/config/livepatch.h) \ + include/uapi/linux/sched.h \ + include/linux/sem.h \ + include/uapi/linux/sem.h \ + include/linux/ipc.h \ + include/uapi/linux/ipc.h \ + arch/x86/include/uapi/asm/ipcbuf.h \ + include/uapi/asm-generic/ipcbuf.h \ + arch/x86/include/uapi/asm/sembuf.h \ + include/linux/shm.h \ + include/uapi/linux/shm.h \ + include/uapi/asm-generic/hugetlb_encode.h \ + arch/x86/include/uapi/asm/shmbuf.h \ + include/uapi/asm-generic/shmbuf.h \ + arch/x86/include/asm/shmparam.h \ + include/linux/kcov.h \ + include/uapi/linux/kcov.h \ + include/linux/plist.h \ + $(wildcard include/config/debug/pi/list.h) \ + include/linux/hrtimer.h \ + $(wildcard include/config/high/res/timers.h) \ + $(wildcard include/config/time/low/res.h) \ + $(wildcard include/config/timerfd.h) \ + include/linux/timerqueue.h \ + include/linux/seccomp.h \ + $(wildcard include/config/seccomp.h) \ + $(wildcard include/config/have/arch/seccomp/filter.h) \ + $(wildcard include/config/seccomp/filter.h) \ + $(wildcard include/config/checkpoint/restore.h) \ + include/uapi/linux/seccomp.h \ + arch/x86/include/asm/seccomp.h \ + arch/x86/include/asm/unistd.h \ + $(wildcard include/config/x86/x32/abi.h) \ + arch/x86/include/uapi/asm/unistd.h \ + arch/x86/include/generated/uapi/asm/unistd_64.h \ + arch/x86/include/generated/asm/unistd_64_x32.h \ + arch/x86/include/asm/ia32_unistd.h \ + arch/x86/include/generated/asm/unistd_32_ia32.h \ + include/asm-generic/seccomp.h \ + include/uapi/linux/unistd.h \ + include/linux/resource.h \ + include/uapi/linux/resource.h \ + arch/x86/include/uapi/asm/resource.h \ + include/asm-generic/resource.h \ + include/uapi/asm-generic/resource.h \ + include/linux/latencytop.h \ + include/linux/sched/prio.h \ + include/linux/signal_types.h \ + $(wildcard include/config/old/sigaction.h) \ + include/uapi/linux/signal.h \ + arch/x86/include/asm/signal.h \ + arch/x86/include/uapi/asm/signal.h \ + include/uapi/asm-generic/signal-defs.h \ + arch/x86/include/uapi/asm/siginfo.h \ + include/uapi/asm-generic/siginfo.h \ + include/linux/task_io_accounting.h \ + $(wildcard include/config/task/io/accounting.h) \ + arch/x86/include/asm/uaccess.h \ + $(wildcard include/config/x86/intel/usercopy.h) \ + arch/x86/include/asm/smap.h \ + $(wildcard include/config/x86/smap.h) \ + arch/x86/include/asm/extable.h \ + arch/x86/include/asm/uaccess_64.h \ + arch/x86/include/asm/checksum.h \ + arch/x86/include/asm/checksum_64.h \ + include/linux/dma-mapping.h \ + $(wildcard include/config/have/generic/dma/coherent.h) \ + $(wildcard include/config/has/dma.h) \ + $(wildcard include/config/arch/has/dma/set/coherent/mask.h) \ + $(wildcard include/config/need/dma/map/state.h) \ + $(wildcard include/config/dma/api/debug.h) \ + include/linux/sizes.h \ + include/linux/device.h \ + $(wildcard include/config/debug/devres.h) \ + $(wildcard include/config/generic/msi/irq/domain.h) \ + $(wildcard include/config/pinctrl.h) \ + $(wildcard include/config/generic/msi/irq.h) \ + $(wildcard include/config/dma/cma.h) \ + $(wildcard include/config/of.h) \ + $(wildcard include/config/devtmpfs.h) \ + $(wildcard include/config/sysfs/deprecated.h) \ + include/linux/ioport.h \ + include/linux/kobject.h \ + $(wildcard include/config/uevent/helper.h) \ + $(wildcard include/config/debug/kobject/release.h) \ + include/linux/sysfs.h \ + include/linux/kernfs.h \ + $(wildcard include/config/kernfs.h) \ + include/linux/kobject_ns.h \ + include/linux/kref.h \ + include/linux/klist.h \ + include/linux/pinctrl/devinfo.h \ + $(wildcard include/config/pm.h) \ + include/linux/pinctrl/consumer.h \ + include/linux/seq_file.h \ + include/linux/cred.h \ + $(wildcard include/config/debug/credentials.h) \ + $(wildcard include/config/keys.h) \ + include/linux/key.h \ + include/linux/assoc_array.h \ + $(wildcard include/config/associative/array.h) \ + include/linux/selinux.h \ + $(wildcard include/config/security/selinux.h) \ + include/linux/sched/user.h \ + $(wildcard include/config/fanotify.h) \ + $(wildcard include/config/posix/mqueue.h) \ + $(wildcard include/config/bpf/syscall.h) \ + $(wildcard include/config/net.h) \ + include/linux/pinctrl/pinctrl-state.h \ + include/linux/pm.h \ + $(wildcard include/config/vt/console/sleep.h) \ + $(wildcard include/config/pm/clk.h) \ + $(wildcard include/config/pm/generic/domains.h) \ + include/linux/ratelimit.h \ + arch/x86/include/asm/device.h \ + $(wildcard include/config/intel/iommu.h) \ + $(wildcard include/config/amd/iommu.h) \ + $(wildcard include/config/x86/dev/dma/ops.h) \ + $(wildcard include/config/pci/domains.h) \ + include/linux/pm_wakeup.h \ + include/linux/dma-debug.h \ + include/linux/dma-direction.h \ + include/linux/scatterlist.h \ + $(wildcard include/config/debug/sg.h) \ + $(wildcard include/config/need/sg/dma/length.h) \ + $(wildcard include/config/sgl/alloc.h) \ + $(wildcard include/config/arch/has/sg/chain.h) \ + $(wildcard include/config/sg/pool.h) \ + include/linux/mm.h \ + $(wildcard include/config/have/arch/mmap/rnd/bits.h) \ + $(wildcard include/config/have/arch/mmap/rnd/compat/bits.h) \ + $(wildcard include/config/arch/uses/high/vma/flags.h) \ + $(wildcard include/config/ppc.h) \ + $(wildcard include/config/parisc.h) \ + $(wildcard include/config/metag.h) \ + $(wildcard include/config/ia64.h) \ + $(wildcard include/config/stack/growsup.h) \ + $(wildcard include/config/device/private.h) \ + $(wildcard include/config/device/public.h) \ + $(wildcard include/config/shmem.h) \ + $(wildcard include/config/have/memblock.h) \ + $(wildcard include/config/debug/vm/rb.h) \ + $(wildcard include/config/page/poisoning.h) \ + $(wildcard include/config/debug/pagealloc.h) \ + $(wildcard include/config/hibernation.h) \ + $(wildcard include/config/hugetlbfs.h) \ + include/linux/percpu-refcount.h \ + include/linux/page_ext.h \ + $(wildcard include/config/idle/page/tracking.h) \ + include/linux/stacktrace.h \ + $(wildcard include/config/stacktrace.h) \ + $(wildcard include/config/user/stacktrace/support.h) \ + include/linux/stackdepot.h \ + include/linux/page_ref.h \ + $(wildcard include/config/debug/page/ref.h) \ + include/linux/page-flags.h \ + $(wildcard include/config/arch/uses/pg/uncached.h) \ + $(wildcard include/config/memory/failure.h) \ + $(wildcard include/config/swap.h) \ + $(wildcard include/config/thp/swap.h) \ + $(wildcard include/config/ksm.h) \ + include/linux/memremap.h \ + arch/x86/include/asm/pgtable.h \ + $(wildcard include/config/debug/wx.h) \ + $(wildcard include/config/have/arch/transparent/hugepage/pud.h) \ + $(wildcard include/config/have/arch/soft/dirty.h) \ + $(wildcard include/config/arch/enable/thp/migration.h) \ + arch/x86/include/asm/pgtable_64.h \ + arch/x86/include/asm/pgtable-invert.h \ + include/asm-generic/pgtable.h \ + $(wildcard include/config/have/arch/huge/vmap.h) \ + $(wildcard include/config/x86/espfix64.h) \ + include/linux/huge_mm.h \ + include/linux/sched/coredump.h \ + $(wildcard include/config/core/dump/default/elf/headers.h) \ + include/linux/vmstat.h \ + $(wildcard include/config/vm/event/counters.h) \ + $(wildcard include/config/debug/tlbflush.h) \ + $(wildcard include/config/debug/vm/vmacache.h) \ + include/linux/vm_event_item.h \ + $(wildcard include/config/memory/balloon.h) \ + $(wildcard include/config/balloon/compaction.h) \ + arch/x86/include/asm/dma-mapping.h \ + $(wildcard include/config/isa.h) \ + $(wildcard include/config/x86/dma/remap.h) \ + arch/x86/include/asm/swiotlb.h \ + $(wildcard include/config/swiotlb.h) \ + include/linux/swiotlb.h \ + include/linux/dma-contiguous.h \ + include/linux/netdev_features.h \ + include/linux/sched/clock.h \ + $(wildcard include/config/have/unstable/sched/clock.h) \ + $(wildcard include/config/irq/time/accounting.h) \ + include/linux/splice.h \ + include/linux/pipe_fs_i.h \ + include/uapi/linux/if_packet.h \ + include/linux/seq_file_net.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + /data/libkernelsepol/libsepol/src/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/node_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/node_record.h \ + /data/libkernelsepol/libsepol/include/sepol/nodes.h \ + +/data/libkernelsepol/libsepol/src/nodes.o: $(deps_/data/libkernelsepol/libsepol/src/nodes.o) + +$(deps_/data/libkernelsepol/libsepol/src/nodes.o): diff --git a/kernel/libsepol/src/.optimize.o.cmd b/kernel/libsepol/src/.optimize.o.cmd new file mode 100644 index 00000000..2866de06 --- /dev/null +++ b/kernel/libsepol/src/.optimize.o.cmd @@ -0,0 +1,606 @@ +cmd_/data/libkernelsepol/libsepol/src/optimize.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.optimize.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"optimize"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_optimize.o /data/libkernelsepol/libsepol/src/optimize.c + +source_/data/libkernelsepol/libsepol/src/optimize.o := /data/libkernelsepol/libsepol/src/optimize.c + +deps_/data/libkernelsepol/libsepol/src/optimize.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + +/data/libkernelsepol/libsepol/src/optimize.o: $(deps_/data/libkernelsepol/libsepol/src/optimize.o) + +$(deps_/data/libkernelsepol/libsepol/src/optimize.o): diff --git a/kernel/libsepol/src/.polcaps.o.cmd b/kernel/libsepol/src/.polcaps.o.cmd new file mode 100644 index 00000000..0c73e661 --- /dev/null +++ b/kernel/libsepol/src/.polcaps.o.cmd @@ -0,0 +1,72 @@ +cmd_/data/libkernelsepol/libsepol/src/polcaps.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.polcaps.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"polcaps"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_polcaps.o /data/libkernelsepol/libsepol/src/polcaps.c + +source_/data/libkernelsepol/libsepol/src/polcaps.o := /data/libkernelsepol/libsepol/src/polcaps.c + +deps_/data/libkernelsepol/libsepol/src/polcaps.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/polcaps.h \ + +/data/libkernelsepol/libsepol/src/polcaps.o: $(deps_/data/libkernelsepol/libsepol/src/polcaps.o) + +$(deps_/data/libkernelsepol/libsepol/src/polcaps.o): diff --git a/kernel/libsepol/src/.policydb.o.cmd b/kernel/libsepol/src/.policydb.o.cmd new file mode 100644 index 00000000..f4d83290 --- /dev/null +++ b/kernel/libsepol/src/.policydb.o.cmd @@ -0,0 +1,613 @@ +cmd_/data/libkernelsepol/libsepol/src/policydb.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.policydb.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"policydb"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_policydb.o /data/libkernelsepol/libsepol/src/policydb.c + +source_/data/libkernelsepol/libsepol/src/policydb.o := /data/libkernelsepol/libsepol/src/policydb.c + +deps_/data/libkernelsepol/libsepol/src/policydb.o := \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avrule_block.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/util.h \ + /data/libkernelsepol/libsepol/src/kernel_to_common.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/mls.h \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + /data/libkernelsepol/libsepol/src/policydb_validate.h \ + +/data/libkernelsepol/libsepol/src/policydb.o: $(deps_/data/libkernelsepol/libsepol/src/policydb.o) + +$(deps_/data/libkernelsepol/libsepol/src/policydb.o): diff --git a/kernel/libsepol/src/.policydb_convert.o.cmd b/kernel/libsepol/src/.policydb_convert.o.cmd new file mode 100644 index 00000000..9c424431 --- /dev/null +++ b/kernel/libsepol/src/.policydb_convert.o.cmd @@ -0,0 +1,605 @@ +cmd_/data/libkernelsepol/libsepol/src/policydb_convert.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.policydb_convert.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"policydb_convert"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_policydb_convert.o /data/libkernelsepol/libsepol/src/policydb_convert.c + +source_/data/libkernelsepol/libsepol/src/policydb_convert.o := /data/libkernelsepol/libsepol/src/policydb_convert.c + +deps_/data/libkernelsepol/libsepol/src/policydb_convert.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + +/data/libkernelsepol/libsepol/src/policydb_convert.o: $(deps_/data/libkernelsepol/libsepol/src/policydb_convert.o) + +$(deps_/data/libkernelsepol/libsepol/src/policydb_convert.o): diff --git a/kernel/libsepol/src/.policydb_public.o.cmd b/kernel/libsepol/src/.policydb_public.o.cmd new file mode 100644 index 00000000..0b77239a --- /dev/null +++ b/kernel/libsepol/src/.policydb_public.o.cmd @@ -0,0 +1,605 @@ +cmd_/data/libkernelsepol/libsepol/src/policydb_public.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.policydb_public.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"policydb_public"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_policydb_public.o /data/libkernelsepol/libsepol/src/policydb_public.c + +source_/data/libkernelsepol/libsepol/src/policydb_public.o := /data/libkernelsepol/libsepol/src/policydb_public.c + +deps_/data/libkernelsepol/libsepol/src/policydb_public.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/kasan.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/smp.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/x86/32.h) \ + $(wildcard include/config/debug/bugverbose.h) \ + include/linux/stringify.h \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + $(wildcard include/config/jump/label.h) \ + include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + +/data/libkernelsepol/libsepol/src/policydb_public.o: $(deps_/data/libkernelsepol/libsepol/src/policydb_public.o) + +$(deps_/data/libkernelsepol/libsepol/src/policydb_public.o): diff --git a/kernel/libsepol/src/.policydb_validate.o.cmd b/kernel/libsepol/src/.policydb_validate.o.cmd new file mode 100644 index 00000000..690c50d6 --- /dev/null +++ b/kernel/libsepol/src/.policydb_validate.o.cmd @@ -0,0 +1,607 @@ +cmd_/data/libkernelsepol/libsepol/src/policydb_validate.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.policydb_validate.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"policydb_validate"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_policydb_validate.o /data/libkernelsepol/libsepol/src/policydb_validate.c + +source_/data/libkernelsepol/libsepol/src/policydb_validate.o := /data/libkernelsepol/libsepol/src/policydb_validate.c + +deps_/data/libkernelsepol/libsepol/src/policydb_validate.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/services.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/policydb_validate.h \ + +/data/libkernelsepol/libsepol/src/policydb_validate.o: $(deps_/data/libkernelsepol/libsepol/src/policydb_validate.o) + +$(deps_/data/libkernelsepol/libsepol/src/policydb_validate.o): diff --git a/kernel/libsepol/src/.port_record.o.cmd b/kernel/libsepol/src/.port_record.o.cmd new file mode 100644 index 00000000..06212177 --- /dev/null +++ b/kernel/libsepol/src/.port_record.o.cmd @@ -0,0 +1,596 @@ +cmd_/data/libkernelsepol/libsepol/src/port_record.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.port_record.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"port_record"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_port_record.o /data/libkernelsepol/libsepol/src/port_record.c + +source_/data/libkernelsepol/libsepol/src/port_record.o := /data/libkernelsepol/libsepol/src/port_record.c + +deps_/data/libkernelsepol/libsepol/src/port_record.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/src/port_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/port_record.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/ports.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/port_record.o: $(deps_/data/libkernelsepol/libsepol/src/port_record.o) + +$(deps_/data/libkernelsepol/libsepol/src/port_record.o): diff --git a/kernel/libsepol/src/.ports.o.cmd b/kernel/libsepol/src/.ports.o.cmd new file mode 100644 index 00000000..3e87afdf --- /dev/null +++ b/kernel/libsepol/src/.ports.o.cmd @@ -0,0 +1,615 @@ +cmd_/data/libkernelsepol/libsepol/src/ports.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.ports.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"ports"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_ports.o /data/libkernelsepol/libsepol/src/ports.c + +source_/data/libkernelsepol/libsepol/src/ports.o := /data/libkernelsepol/libsepol/src/ports.c + +deps_/data/libkernelsepol/libsepol/src/ports.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/in.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + include/uapi/linux/in.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + include/uapi/linux/libc-compat.h \ + $(wildcard include/config/data.h) \ + include/linux/socket.h \ + $(wildcard include/config/proc/fs.h) \ + $(wildcard include/config/compat.h) \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/linux/linkage.h \ + include/linux/stringify.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/64.h) \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + $(wildcard include/config/kasan.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + $(wildcard include/config/jump/label.h) \ + include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h \ + include/linux/build_bug.h \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/restart_block.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + $(wildcard include/config/sparsemem.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + /data/libkernelsepol/libsepol/src/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/port_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/port_record.h \ + /data/libkernelsepol/libsepol/include/sepol/ports.h \ + +/data/libkernelsepol/libsepol/src/ports.o: $(deps_/data/libkernelsepol/libsepol/src/ports.o) + +$(deps_/data/libkernelsepol/libsepol/src/ports.o): diff --git a/kernel/libsepol/src/.services.o.cmd b/kernel/libsepol/src/.services.o.cmd new file mode 100644 index 00000000..35909b20 --- /dev/null +++ b/kernel/libsepol/src/.services.o.cmd @@ -0,0 +1,1062 @@ +cmd_/data/libkernelsepol/libsepol/src/services.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.services.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"services"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_services.o /data/libkernelsepol/libsepol/src/services.c + +source_/data/libkernelsepol/libsepol/src/services.o := /data/libkernelsepol/libsepol/src/services.c + +deps_/data/libkernelsepol/libsepol/src/services.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + include/linux/socket.h \ + $(wildcard include/config/proc/fs.h) \ + $(wildcard include/config/compat.h) \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/tracing.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/linux/linkage.h \ + include/linux/stringify.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/64.h) \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + $(wildcard include/config/kasan.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + $(wildcard include/config/jump/label.h) \ + include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h \ + include/linux/build_bug.h \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/restart_block.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + $(wildcard include/config/sparsemem.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + include/linux/in.h \ + include/uapi/linux/in.h \ + include/uapi/linux/libc-compat.h \ + $(wildcard include/config/data.h) \ + include/linux/inet.h \ + include/net/net_namespace.h \ + $(wildcard include/config/nf/conntrack.h) \ + $(wildcard include/config/sysctl.h) \ + $(wildcard include/config/ipv6.h) \ + $(wildcard include/config/ieee802154/6lowpan.h) \ + $(wildcard include/config/ip/sctp.h) \ + $(wildcard include/config/ip/dccp.h) \ + $(wildcard include/config/netfilter.h) \ + $(wildcard include/config/nf/tables.h) \ + $(wildcard include/config/nf/defrag/ipv6.h) \ + $(wildcard include/config/netfilter/netlink/acct.h) \ + $(wildcard include/config/nf/ct/netlink/timeout.h) \ + $(wildcard include/config/wext/core.h) \ + $(wildcard include/config/xfrm.h) \ + $(wildcard include/config/ip/vs.h) \ + $(wildcard include/config/mpls.h) \ + $(wildcard include/config/can.h) \ + $(wildcard include/config/net/ns.h) \ + include/linux/refcount.h \ + $(wildcard include/config/refcount/full.h) \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + include/linux/spinlock_types.h \ + $(wildcard include/config/debug/spinlock.h) \ + include/linux/lockdep.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/preempt.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + arch/x86/include/asm/preempt.h \ + include/linux/bottom_half.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + arch/x86/include/asm/refcount.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/seqlock.h \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/sysctl.h \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/rbtree.h \ + include/linux/uidgid.h \ + $(wildcard include/config/multiuser.h) \ + $(wildcard include/config/user/ns.h) \ + include/linux/highuid.h \ + include/uapi/linux/sysctl.h \ + include/net/flow.h \ + include/linux/in6.h \ + include/uapi/linux/in6.h \ + include/net/flow_dissector.h \ + include/linux/siphash.h \ + $(wildcard include/config/have/efficient/unaligned/access.h) \ + include/uapi/linux/if_ether.h \ + include/net/netns/core.h \ + include/net/netns/mib.h \ + $(wildcard include/config/xfrm/statistics.h) \ + include/net/snmp.h \ + include/uapi/linux/snmp.h \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/numa/emu.h) \ + include/linux/nodemask.h \ + $(wildcard include/config/highmem.h) \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/u64_stats_sync.h \ + include/net/netns/unix.h \ + include/net/netns/packet.h \ + include/linux/rculist.h \ + include/net/netns/ipv4.h \ + $(wildcard include/config/ip/multiple/tables.h) \ + $(wildcard include/config/ip/route/classid.h) \ + $(wildcard include/config/security.h) \ + $(wildcard include/config/net/l3/master/dev.h) \ + $(wildcard include/config/ip/mroute.h) \ + $(wildcard include/config/ip/mroute/multiple/tables.h) \ + $(wildcard include/config/ip/route/multipath.h) \ + include/net/inet_frag.h \ + include/linux/rhashtable.h \ + include/linux/jhash.h \ + include/linux/unaligned/packed_struct.h \ + include/linux/list_nulls.h \ + include/net/netns/ipv6.h \ + $(wildcard include/config/ipv6/multiple/tables.h) \ + $(wildcard include/config/ipv6/mroute.h) \ + $(wildcard include/config/ipv6/mroute/multiple/tables.h) \ + include/net/dst_ops.h \ + include/linux/percpu_counter.h \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/gfp.h \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/net/netns/ieee802154_6lowpan.h \ + include/net/netns/sctp.h \ + include/net/netns/dccp.h \ + include/net/netns/netfilter.h \ + $(wildcard include/config/nf/defrag/ipv4.h) \ + include/linux/netfilter_defs.h \ + include/uapi/linux/netfilter.h \ + include/net/netns/x_tables.h \ + $(wildcard include/config/bridge/nf/ebtables.h) \ + include/net/netns/conntrack.h \ + $(wildcard include/config/nf/ct/proto/dccp.h) \ + $(wildcard include/config/nf/ct/proto/sctp.h) \ + $(wildcard include/config/nf/conntrack/events.h) \ + $(wildcard include/config/nf/conntrack/labels.h) \ + include/linux/netfilter/nf_conntrack_tcp.h \ + include/uapi/linux/netfilter/nf_conntrack_tcp.h \ + include/linux/netfilter/nf_conntrack_dccp.h \ + include/uapi/linux/netfilter/nf_conntrack_tuple_common.h \ + include/linux/netfilter/nf_conntrack_common.h \ + include/uapi/linux/netfilter/nf_conntrack_common.h \ + include/linux/netfilter/nf_conntrack_sctp.h \ + include/uapi/linux/netfilter/nf_conntrack_sctp.h \ + include/net/netns/nftables.h \ + include/net/netns/xfrm.h \ + include/uapi/linux/xfrm.h \ + include/net/netns/mpls.h \ + include/net/netns/can.h \ + include/linux/ns_common.h \ + include/linux/idr.h \ + include/linux/radix-tree.h \ + $(wildcard include/config/radix/tree/multiorder.h) \ + include/linux/skbuff.h \ + $(wildcard include/config/bridge/netfilter.h) \ + $(wildcard include/config/ipv6/ndisc/nodetype.h) \ + $(wildcard include/config/net/switchdev.h) \ + $(wildcard include/config/net/cls/act.h) \ + $(wildcard include/config/net/sched.h) \ + $(wildcard include/config/net/rx/busy/poll.h) \ + $(wildcard include/config/xps.h) \ + $(wildcard include/config/network/secmark.h) \ + $(wildcard include/config/network/phy/timestamping.h) \ + $(wildcard include/config/netfilter/xt/target/trace.h) \ + include/linux/net.h \ + include/linux/random.h \ + $(wildcard include/config/gcc/plugin/latent/entropy.h) \ + $(wildcard include/config/arch/random.h) \ + include/linux/once.h \ + include/uapi/linux/random.h \ + include/linux/irqnr.h \ + include/uapi/linux/irqnr.h \ + include/linux/prandom.h \ + arch/x86/include/asm/archrandom.h \ + include/linux/fcntl.h \ + include/uapi/linux/fcntl.h \ + arch/x86/include/uapi/asm/fcntl.h \ + include/uapi/asm-generic/fcntl.h \ + include/linux/fs.h \ + $(wildcard include/config/fs/posix/acl.h) \ + $(wildcard include/config/cgroup/writeback.h) \ + $(wildcard include/config/ima.h) \ + $(wildcard include/config/fsnotify.h) \ + $(wildcard include/config/fs/encryption.h) \ + $(wildcard include/config/epoll.h) \ + $(wildcard include/config/file/locking.h) \ + $(wildcard include/config/quota.h) \ + $(wildcard include/config/blk/dev/loop.h) \ + $(wildcard include/config/fs/dax.h) \ + $(wildcard include/config/block.h) \ + $(wildcard include/config/mandatory/file/locking.h) \ + $(wildcard include/config/migration.h) \ + include/linux/wait_bit.h \ + include/linux/kdev_t.h \ + include/uapi/linux/kdev_t.h \ + include/linux/dcache.h \ + include/linux/rculist_bl.h \ + include/linux/list_bl.h \ + include/linux/bit_spinlock.h \ + include/linux/lockref.h \ + $(wildcard include/config/arch/use/cmpxchg/lockref.h) \ + include/linux/stringhash.h \ + $(wildcard include/config/dcache/word/access.h) \ + include/linux/hash.h \ + $(wildcard include/config/have/arch/hash.h) \ + include/linux/path.h \ + include/linux/stat.h \ + arch/x86/include/uapi/asm/stat.h \ + include/uapi/linux/stat.h \ + include/linux/list_lru.h \ + $(wildcard include/config/slob.h) \ + include/linux/shrinker.h \ + include/linux/pid.h \ + include/linux/mm_types.h \ + $(wildcard include/config/have/cmpxchg/double.h) \ + $(wildcard include/config/have/aligned/struct/page.h) \ + $(wildcard include/config/userfaultfd.h) \ + $(wildcard include/config/have/arch/compat/mmap/bases.h) \ + $(wildcard include/config/membarrier.h) \ + $(wildcard include/config/aio.h) \ + $(wildcard include/config/mmu/notifier.h) \ + $(wildcard include/config/arch/want/batched/unmap/tlb/flush.h) \ + $(wildcard include/config/hmm.h) \ + include/linux/mm_types_task.h \ + $(wildcard include/config/split/ptlock/cpus.h) \ + $(wildcard include/config/arch/enable/split/pmd/ptlock.h) \ + arch/x86/include/asm/tlbbatch.h \ + include/linux/auxvec.h \ + include/uapi/linux/auxvec.h \ + arch/x86/include/uapi/asm/auxvec.h \ + include/linux/uprobes.h \ + $(wildcard include/config/uprobes.h) \ + arch/x86/include/asm/uprobes.h \ + include/linux/capability.h \ + include/uapi/linux/capability.h \ + include/linux/semaphore.h \ + include/uapi/linux/fiemap.h \ + include/linux/migrate_mode.h \ + include/linux/percpu-rwsem.h \ + include/linux/rcuwait.h \ + include/linux/rcu_sync.h \ + include/linux/delayed_call.h \ + include/linux/uuid.h \ + include/uapi/linux/uuid.h \ + include/linux/errseq.h \ + include/uapi/linux/fs.h \ + include/uapi/linux/limits.h \ + include/linux/quota.h \ + $(wildcard include/config/quota/netlink/interface.h) \ + include/uapi/linux/dqblk_xfs.h \ + include/linux/dqblk_v1.h \ + include/linux/dqblk_v2.h \ + include/linux/dqblk_qtree.h \ + include/linux/projid.h \ + include/uapi/linux/quota.h \ + include/linux/nfs_fs_i.h \ + include/uapi/linux/net.h \ + include/linux/textsearch.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/net/checksum.h \ + include/linux/uaccess.h \ + include/linux/sched.h \ + $(wildcard include/config/virt/cpu/accounting/native.h) \ + $(wildcard include/config/sched/info.h) \ + $(wildcard include/config/schedstats.h) \ + $(wildcard include/config/fair/group/sched.h) \ + $(wildcard include/config/rt/group/sched.h) \ + $(wildcard include/config/cgroup/sched.h) \ + $(wildcard include/config/blk/dev/io/trace.h) \ + $(wildcard include/config/compat/brk.h) \ + $(wildcard include/config/cgroups.h) \ + $(wildcard include/config/arch/has/scaled/cputime.h) \ + $(wildcard include/config/virt/cpu/accounting/gen.h) \ + $(wildcard include/config/posix/timers.h) \ + $(wildcard include/config/sysvipc.h) \ + $(wildcard include/config/detect/hung/task.h) \ + $(wildcard include/config/auditsyscall.h) \ + $(wildcard include/config/rt/mutexes.h) \ + $(wildcard include/config/ubsan.h) \ + $(wildcard include/config/task/xacct.h) \ + $(wildcard include/config/cpusets.h) \ + $(wildcard include/config/intel/rdt.h) \ + $(wildcard include/config/futex.h) \ + $(wildcard include/config/perf/events.h) \ + $(wildcard include/config/task/delay/acct.h) \ + $(wildcard include/config/fault/injection.h) \ + $(wildcard include/config/latencytop.h) \ + $(wildcard include/config/function/graph/tracer.h) \ + $(wildcard include/config/kcov.h) \ + $(wildcard include/config/bcache.h) \ + $(wildcard include/config/vmap/stack.h) \ + $(wildcard include/config/livepatch.h) \ + include/uapi/linux/sched.h \ + include/linux/sem.h \ + include/uapi/linux/sem.h \ + include/linux/ipc.h \ + include/uapi/linux/ipc.h \ + arch/x86/include/uapi/asm/ipcbuf.h \ + include/uapi/asm-generic/ipcbuf.h \ + arch/x86/include/uapi/asm/sembuf.h \ + include/linux/shm.h \ + include/uapi/linux/shm.h \ + include/uapi/asm-generic/hugetlb_encode.h \ + arch/x86/include/uapi/asm/shmbuf.h \ + include/uapi/asm-generic/shmbuf.h \ + arch/x86/include/asm/shmparam.h \ + include/linux/kcov.h \ + include/uapi/linux/kcov.h \ + include/linux/plist.h \ + $(wildcard include/config/debug/pi/list.h) \ + include/linux/hrtimer.h \ + $(wildcard include/config/high/res/timers.h) \ + $(wildcard include/config/time/low/res.h) \ + $(wildcard include/config/timerfd.h) \ + include/linux/timerqueue.h \ + include/linux/seccomp.h \ + $(wildcard include/config/seccomp.h) \ + $(wildcard include/config/have/arch/seccomp/filter.h) \ + $(wildcard include/config/seccomp/filter.h) \ + $(wildcard include/config/checkpoint/restore.h) \ + include/uapi/linux/seccomp.h \ + arch/x86/include/asm/seccomp.h \ + arch/x86/include/asm/unistd.h \ + $(wildcard include/config/x86/x32/abi.h) \ + arch/x86/include/uapi/asm/unistd.h \ + arch/x86/include/generated/uapi/asm/unistd_64.h \ + arch/x86/include/generated/asm/unistd_64_x32.h \ + arch/x86/include/asm/ia32_unistd.h \ + arch/x86/include/generated/asm/unistd_32_ia32.h \ + include/asm-generic/seccomp.h \ + include/uapi/linux/unistd.h \ + include/linux/resource.h \ + include/uapi/linux/resource.h \ + arch/x86/include/uapi/asm/resource.h \ + include/asm-generic/resource.h \ + include/uapi/asm-generic/resource.h \ + include/linux/latencytop.h \ + include/linux/sched/prio.h \ + include/linux/signal_types.h \ + $(wildcard include/config/old/sigaction.h) \ + include/uapi/linux/signal.h \ + arch/x86/include/asm/signal.h \ + arch/x86/include/uapi/asm/signal.h \ + include/uapi/asm-generic/signal-defs.h \ + arch/x86/include/uapi/asm/siginfo.h \ + include/uapi/asm-generic/siginfo.h \ + include/linux/task_io_accounting.h \ + $(wildcard include/config/task/io/accounting.h) \ + arch/x86/include/asm/uaccess.h \ + $(wildcard include/config/x86/intel/usercopy.h) \ + arch/x86/include/asm/smap.h \ + $(wildcard include/config/x86/smap.h) \ + arch/x86/include/asm/extable.h \ + arch/x86/include/asm/uaccess_64.h \ + arch/x86/include/asm/checksum.h \ + arch/x86/include/asm/checksum_64.h \ + include/linux/dma-mapping.h \ + $(wildcard include/config/have/generic/dma/coherent.h) \ + $(wildcard include/config/has/dma.h) \ + $(wildcard include/config/arch/has/dma/set/coherent/mask.h) \ + $(wildcard include/config/need/dma/map/state.h) \ + $(wildcard include/config/dma/api/debug.h) \ + include/linux/sizes.h \ + include/linux/device.h \ + $(wildcard include/config/debug/devres.h) \ + $(wildcard include/config/generic/msi/irq/domain.h) \ + $(wildcard include/config/pinctrl.h) \ + $(wildcard include/config/generic/msi/irq.h) \ + $(wildcard include/config/dma/cma.h) \ + $(wildcard include/config/of.h) \ + $(wildcard include/config/devtmpfs.h) \ + $(wildcard include/config/sysfs/deprecated.h) \ + include/linux/ioport.h \ + include/linux/kobject.h \ + $(wildcard include/config/uevent/helper.h) \ + $(wildcard include/config/debug/kobject/release.h) \ + include/linux/sysfs.h \ + include/linux/kernfs.h \ + $(wildcard include/config/kernfs.h) \ + include/linux/kobject_ns.h \ + include/linux/kref.h \ + include/linux/klist.h \ + include/linux/pinctrl/devinfo.h \ + $(wildcard include/config/pm.h) \ + include/linux/pinctrl/consumer.h \ + include/linux/seq_file.h \ + include/linux/cred.h \ + $(wildcard include/config/debug/credentials.h) \ + $(wildcard include/config/keys.h) \ + include/linux/key.h \ + include/linux/assoc_array.h \ + $(wildcard include/config/associative/array.h) \ + include/linux/selinux.h \ + $(wildcard include/config/security/selinux.h) \ + include/linux/sched/user.h \ + $(wildcard include/config/fanotify.h) \ + $(wildcard include/config/posix/mqueue.h) \ + $(wildcard include/config/bpf/syscall.h) \ + $(wildcard include/config/net.h) \ + include/linux/pinctrl/pinctrl-state.h \ + include/linux/pm.h \ + $(wildcard include/config/vt/console/sleep.h) \ + $(wildcard include/config/pm/clk.h) \ + $(wildcard include/config/pm/generic/domains.h) \ + include/linux/ratelimit.h \ + arch/x86/include/asm/device.h \ + $(wildcard include/config/intel/iommu.h) \ + $(wildcard include/config/amd/iommu.h) \ + $(wildcard include/config/x86/dev/dma/ops.h) \ + $(wildcard include/config/pci/domains.h) \ + include/linux/pm_wakeup.h \ + include/linux/dma-debug.h \ + include/linux/dma-direction.h \ + include/linux/scatterlist.h \ + $(wildcard include/config/debug/sg.h) \ + $(wildcard include/config/need/sg/dma/length.h) \ + $(wildcard include/config/sgl/alloc.h) \ + $(wildcard include/config/arch/has/sg/chain.h) \ + $(wildcard include/config/sg/pool.h) \ + include/linux/mm.h \ + $(wildcard include/config/have/arch/mmap/rnd/bits.h) \ + $(wildcard include/config/have/arch/mmap/rnd/compat/bits.h) \ + $(wildcard include/config/arch/uses/high/vma/flags.h) \ + $(wildcard include/config/ppc.h) \ + $(wildcard include/config/parisc.h) \ + $(wildcard include/config/metag.h) \ + $(wildcard include/config/ia64.h) \ + $(wildcard include/config/stack/growsup.h) \ + $(wildcard include/config/device/private.h) \ + $(wildcard include/config/device/public.h) \ + $(wildcard include/config/shmem.h) \ + $(wildcard include/config/have/memblock.h) \ + $(wildcard include/config/debug/vm/rb.h) \ + $(wildcard include/config/page/poisoning.h) \ + $(wildcard include/config/debug/pagealloc.h) \ + $(wildcard include/config/hibernation.h) \ + $(wildcard include/config/hugetlbfs.h) \ + include/linux/percpu-refcount.h \ + include/linux/page_ext.h \ + $(wildcard include/config/idle/page/tracking.h) \ + include/linux/stacktrace.h \ + $(wildcard include/config/stacktrace.h) \ + $(wildcard include/config/user/stacktrace/support.h) \ + include/linux/stackdepot.h \ + include/linux/page_ref.h \ + $(wildcard include/config/debug/page/ref.h) \ + include/linux/page-flags.h \ + $(wildcard include/config/arch/uses/pg/uncached.h) \ + $(wildcard include/config/memory/failure.h) \ + $(wildcard include/config/swap.h) \ + $(wildcard include/config/thp/swap.h) \ + $(wildcard include/config/ksm.h) \ + include/linux/memremap.h \ + arch/x86/include/asm/pgtable.h \ + $(wildcard include/config/debug/wx.h) \ + $(wildcard include/config/have/arch/transparent/hugepage/pud.h) \ + $(wildcard include/config/have/arch/soft/dirty.h) \ + $(wildcard include/config/arch/enable/thp/migration.h) \ + arch/x86/include/asm/pgtable_64.h \ + arch/x86/include/asm/pgtable-invert.h \ + include/asm-generic/pgtable.h \ + $(wildcard include/config/have/arch/huge/vmap.h) \ + $(wildcard include/config/x86/espfix64.h) \ + include/linux/huge_mm.h \ + include/linux/sched/coredump.h \ + $(wildcard include/config/core/dump/default/elf/headers.h) \ + include/linux/vmstat.h \ + $(wildcard include/config/vm/event/counters.h) \ + $(wildcard include/config/debug/tlbflush.h) \ + $(wildcard include/config/debug/vm/vmacache.h) \ + include/linux/vm_event_item.h \ + $(wildcard include/config/memory/balloon.h) \ + $(wildcard include/config/balloon/compaction.h) \ + arch/x86/include/asm/dma-mapping.h \ + $(wildcard include/config/isa.h) \ + $(wildcard include/config/x86/dma/remap.h) \ + arch/x86/include/asm/swiotlb.h \ + $(wildcard include/config/swiotlb.h) \ + include/linux/swiotlb.h \ + include/linux/dma-contiguous.h \ + include/linux/netdev_features.h \ + include/linux/sched/clock.h \ + $(wildcard include/config/have/unstable/sched/clock.h) \ + $(wildcard include/config/irq/time/accounting.h) \ + include/linux/splice.h \ + include/linux/pipe_fs_i.h \ + include/uapi/linux/if_packet.h \ + include/linux/seq_file_net.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/services.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/util.h \ + /data/libkernelsepol/libsepol/include/sepol/sepol.h \ + /data/libkernelsepol/libsepol/include/sepol/user_record.h \ + /data/libkernelsepol/libsepol/include/sepol/context_record.h \ + /data/libkernelsepol/libsepol/include/sepol/iface_record.h \ + /data/libkernelsepol/libsepol/include/sepol/ibpkey_record.h \ + /data/libkernelsepol/libsepol/include/sepol/ibendport_record.h \ + /data/libkernelsepol/libsepol/include/sepol/port_record.h \ + /data/libkernelsepol/libsepol/include/sepol/boolean_record.h \ + /data/libkernelsepol/libsepol/include/sepol/node_record.h \ + /data/libkernelsepol/libsepol/include/sepol/booleans.h \ + /data/libkernelsepol/libsepol/include/sepol/interfaces.h \ + /data/libkernelsepol/libsepol/include/sepol/ibpkeys.h \ + /data/libkernelsepol/libsepol/include/sepol/ibendports.h \ + /data/libkernelsepol/libsepol/include/sepol/ports.h \ + /data/libkernelsepol/libsepol/include/sepol/nodes.h \ + /data/libkernelsepol/libsepol/include/sepol/users.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/module.h \ + /data/libkernelsepol/libsepol/include/sepol/context.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/src/context.h \ + /data/libkernelsepol/libsepol/src/context_internal.h \ + /data/libkernelsepol/libsepol/src/mls.h \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + /data/libkernelsepol/libsepol/src/flask.h \ + +/data/libkernelsepol/libsepol/src/services.o: $(deps_/data/libkernelsepol/libsepol/src/services.o) + +$(deps_/data/libkernelsepol/libsepol/src/services.o): diff --git a/kernel/libsepol/src/.sidtab.o.cmd b/kernel/libsepol/src/.sidtab.o.cmd new file mode 100644 index 00000000..5f70adcf --- /dev/null +++ b/kernel/libsepol/src/.sidtab.o.cmd @@ -0,0 +1,604 @@ +cmd_/data/libkernelsepol/libsepol/src/sidtab.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.sidtab.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"sidtab"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_sidtab.o /data/libkernelsepol/libsepol/src/sidtab.c + +source_/data/libkernelsepol/libsepol/src/sidtab.o := /data/libkernelsepol/libsepol/src/sidtab.c + +deps_/data/libkernelsepol/libsepol/src/sidtab.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/uapi/linux/limits.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/src/flask.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/sidtab.o: $(deps_/data/libkernelsepol/libsepol/src/sidtab.o) + +$(deps_/data/libkernelsepol/libsepol/src/sidtab.o): diff --git a/kernel/libsepol/src/.symtab.o.cmd b/kernel/libsepol/src/.symtab.o.cmd new file mode 100644 index 00000000..f147c1f4 --- /dev/null +++ b/kernel/libsepol/src/.symtab.o.cmd @@ -0,0 +1,602 @@ +cmd_/data/libkernelsepol/libsepol/src/symtab.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.symtab.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"symtab"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_symtab.o /data/libkernelsepol/libsepol/src/symtab.c + +source_/data/libkernelsepol/libsepol/src/symtab.o := /data/libkernelsepol/libsepol/src/symtab.c + +deps_/data/libkernelsepol/libsepol/src/symtab.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/symtab.o: $(deps_/data/libkernelsepol/libsepol/src/symtab.o) + +$(deps_/data/libkernelsepol/libsepol/src/symtab.o): diff --git a/kernel/libsepol/src/.user_record.o.cmd b/kernel/libsepol/src/.user_record.o.cmd new file mode 100644 index 00000000..25b62fc1 --- /dev/null +++ b/kernel/libsepol/src/.user_record.o.cmd @@ -0,0 +1,608 @@ +cmd_/data/libkernelsepol/libsepol/src/user_record.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.user_record.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"user_record"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_user_record.o /data/libkernelsepol/libsepol/src/user_record.c + +source_/data/libkernelsepol/libsepol/src/user_record.o := /data/libkernelsepol/libsepol/src/user_record.c + +deps_/data/libkernelsepol/libsepol/src/user_record.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/src/user_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/user_record.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/users.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + +/data/libkernelsepol/libsepol/src/user_record.o: $(deps_/data/libkernelsepol/libsepol/src/user_record.o) + +$(deps_/data/libkernelsepol/libsepol/src/user_record.o): diff --git a/kernel/libsepol/src/.users.o.cmd b/kernel/libsepol/src/.users.o.cmd new file mode 100644 index 00000000..8c8c212f --- /dev/null +++ b/kernel/libsepol/src/.users.o.cmd @@ -0,0 +1,612 @@ +cmd_/data/libkernelsepol/libsepol/src/users.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.users.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"users"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_users.o /data/libkernelsepol/libsepol/src/users.c + +source_/data/libkernelsepol/libsepol/src/users.o := /data/libkernelsepol/libsepol/src/users.c + +deps_/data/libkernelsepol/libsepol/src/users.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/src/user_internal.h \ + /data/libkernelsepol/libsepol/include/sepol/user_record.h \ + /data/libkernelsepol/libsepol/include/sepol/users.h \ + /data/libkernelsepol/libsepol/src/mls.h \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + +/data/libkernelsepol/libsepol/src/users.o: $(deps_/data/libkernelsepol/libsepol/src/users.o) + +$(deps_/data/libkernelsepol/libsepol/src/users.o): diff --git a/kernel/libsepol/src/.util.o.cmd b/kernel/libsepol/src/.util.o.cmd new file mode 100644 index 00000000..46cb9109 --- /dev/null +++ b/kernel/libsepol/src/.util.o.cmd @@ -0,0 +1,604 @@ +cmd_/data/libkernelsepol/libsepol/src/util.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.util.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"util"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_util.o /data/libkernelsepol/libsepol/src/util.c + +source_/data/libkernelsepol/libsepol/src/util.o := /data/libkernelsepol/libsepol/src/util.c + +deps_/data/libkernelsepol/libsepol/src/util.o := \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + include/linux/ctype.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + $(wildcard include/config/64bit.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/util.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + +/data/libkernelsepol/libsepol/src/util.o: $(deps_/data/libkernelsepol/libsepol/src/util.o) + +$(deps_/data/libkernelsepol/libsepol/src/util.o): diff --git a/kernel/libsepol/src/.write.o.cmd b/kernel/libsepol/src/.write.o.cmd new file mode 100644 index 00000000..1a10d216 --- /dev/null +++ b/kernel/libsepol/src/.write.o.cmd @@ -0,0 +1,609 @@ +cmd_/data/libkernelsepol/libsepol/src/write.o := gcc -Wp,-MD,/data/libkernelsepol/libsepol/src/.write.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Werror=return-type -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -I/data/libkernelsepol/libsepol/include -DMODULE -DKBUILD_BASENAME='"write"' -DKBUILD_MODNAME='"hello"' -c -o /data/libkernelsepol/libsepol/src/.tmp_write.o /data/libkernelsepol/libsepol/src/write.c + +source_/data/libkernelsepol/libsepol/src/write.o := /data/libkernelsepol/libsepol/src/write.c + +deps_/data/libkernelsepol/libsepol/src/write.o := \ + $(wildcard include/config/mls.h) \ + $(wildcard include/config/unknown/mask.h) \ + include/linux/compiler_types.h \ + $(wildcard include/config/have/arch/compiler/h.h) \ + $(wildcard include/config/enable/must/check.h) \ + $(wildcard include/config/enable/warn/deprecated.h) \ + include/linux/compiler-gcc.h \ + $(wildcard include/config/arch/supports/optimized/inlining.h) \ + $(wildcard include/config/optimize/inlining.h) \ + $(wildcard include/config/retpoline.h) \ + $(wildcard include/config/arm64.h) \ + $(wildcard include/config/gcov/kernel.h) \ + $(wildcard include/config/arch/use/builtin/bswap.h) \ + /data/libkernelsepol/libsepol/include/sepol/policydb/ebitmap.h \ + include/linux/string.h \ + $(wildcard include/config/binary/printf.h) \ + $(wildcard include/config/fortify/source.h) \ + $(wildcard include/config/kasan.h) \ + include/linux/compiler.h \ + $(wildcard include/config/trace/branch/profiling.h) \ + $(wildcard include/config/profile/all/branches.h) \ + $(wildcard include/config/stack/validation.h) \ + include/uapi/linux/types.h \ + arch/x86/include/uapi/asm/types.h \ + include/uapi/asm-generic/types.h \ + include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h \ + $(wildcard include/config/64bit.h) \ + include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h \ + include/linux/stddef.h \ + include/uapi/linux/stddef.h \ + arch/x86/include/asm/posix_types.h \ + $(wildcard include/config/x86/32.h) \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h \ + arch/x86/include/asm/barrier.h \ + $(wildcard include/config/x86/ppro/fence.h) \ + arch/x86/include/asm/alternative.h \ + $(wildcard include/config/smp.h) \ + include/linux/types.h \ + $(wildcard include/config/have/uid16.h) \ + $(wildcard include/config/uid16.h) \ + $(wildcard include/config/lbdaf.h) \ + $(wildcard include/config/arch/dma/addr/t/64bit.h) \ + $(wildcard include/config/phys/addr/t/64bit.h) \ + include/linux/stringify.h \ + arch/x86/include/asm/asm.h \ + arch/x86/include/asm/nops.h \ + $(wildcard include/config/mk7.h) \ + $(wildcard include/config/x86/p6/nop.h) \ + $(wildcard include/config/x86/64.h) \ + include/asm-generic/barrier.h \ + include/linux/kasan-checks.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + include/uapi/linux/string.h \ + arch/x86/include/asm/string.h \ + arch/x86/include/asm/string_64.h \ + $(wildcard include/config/x86/mce.h) \ + $(wildcard include/config/arch/has/uaccess/flushcache.h) \ + include/linux/jump_label.h \ + $(wildcard include/config/jump/label.h) \ + arch/x86/include/asm/jump_label.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/avtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb.h \ + /data/libkernelsepol/libsepol/include/sepol/handle.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/flask_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/symtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/hashtab.h \ + /data/libkernelsepol/libsepol/include/sepol/errcodes.h \ + include/linux/errno.h \ + include/uapi/linux/errno.h \ + arch/x86/include/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h \ + include/uapi/asm-generic/errno-base.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/context.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/mls_types.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/constraint.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/sidtab.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/conditional.h \ + /data/libkernelsepol/libsepol/include/sepol/policydb/expand.h \ + /data/libkernelsepol/libsepol/src/debug.h \ + /data/libkernelsepol/libsepol/include/sepol/debug.h \ + /data/libkernelsepol/libsepol/src/handle.h \ + /data/libkernelsepol/libsepol/src/kernel.h \ + include/linux/slab.h \ + $(wildcard include/config/debug/slab.h) \ + $(wildcard include/config/debug/objects.h) \ + $(wildcard include/config/failslab.h) \ + $(wildcard include/config/memcg.h) \ + $(wildcard include/config/slob.h) \ + $(wildcard include/config/have/hardened/usercopy/allocator.h) \ + $(wildcard include/config/slab.h) \ + $(wildcard include/config/slub.h) \ + $(wildcard include/config/zone/dma.h) \ + $(wildcard include/config/numa.h) \ + $(wildcard include/config/tracing.h) \ + include/linux/gfp.h \ + $(wildcard include/config/lockdep.h) \ + $(wildcard include/config/highmem.h) \ + $(wildcard include/config/zone/dma32.h) \ + $(wildcard include/config/zone/device.h) \ + $(wildcard include/config/pm/sleep.h) \ + $(wildcard include/config/memory/isolation.h) \ + $(wildcard include/config/compaction.h) \ + $(wildcard include/config/cma.h) \ + include/linux/mmdebug.h \ + $(wildcard include/config/debug/vm.h) \ + $(wildcard include/config/debug/virtual.h) \ + $(wildcard include/config/debug/vm/pgflags.h) \ + include/linux/bug.h \ + $(wildcard include/config/generic/bug.h) \ + $(wildcard include/config/bug/on/data/corruption.h) \ + arch/x86/include/asm/bug.h \ + $(wildcard include/config/debug/bugverbose.h) \ + include/asm-generic/bug.h \ + $(wildcard include/config/bug.h) \ + $(wildcard include/config/generic/bug/relative/pointers.h) \ + include/linux/kernel.h \ + $(wildcard include/config/preempt/voluntary.h) \ + $(wildcard include/config/debug/atomic/sleep.h) \ + $(wildcard include/config/mmu.h) \ + $(wildcard include/config/prove/locking.h) \ + $(wildcard include/config/arch/has/refcount.h) \ + $(wildcard include/config/lock/down/kernel.h) \ + $(wildcard include/config/panic/timeout.h) \ + $(wildcard include/config/ftrace/mcount/record.h) \ + include/linux/linkage.h \ + include/linux/export.h \ + $(wildcard include/config/have/underscore/symbol/prefix.h) \ + $(wildcard include/config/modules.h) \ + $(wildcard include/config/modversions.h) \ + $(wildcard include/config/module/rel/crcs.h) \ + $(wildcard include/config/trim/unused/ksyms.h) \ + $(wildcard include/config/unused/symbols.h) \ + arch/x86/include/asm/linkage.h \ + $(wildcard include/config/x86/alignment/16.h) \ + include/linux/bitops.h \ + include/linux/bits.h \ + arch/x86/include/asm/bitops.h \ + $(wildcard include/config/x86/cmov.h) \ + arch/x86/include/asm/rmwcc.h \ + include/asm-generic/bitops/find.h \ + $(wildcard include/config/generic/find/first/bit.h) \ + include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h \ + arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + $(wildcard include/config/x86/minimum/cpu/family.h) \ + $(wildcard include/config/math/emulation.h) \ + $(wildcard include/config/x86/pae.h) \ + $(wildcard include/config/x86/cmpxchg64.h) \ + $(wildcard include/config/x86/use/3dnow.h) \ + $(wildcard include/config/matom.h) \ + $(wildcard include/config/x86/5level.h) \ + $(wildcard include/config/paravirt.h) \ + arch/x86/include/asm/disabled-features.h \ + $(wildcard include/config/x86/intel/mpx.h) \ + $(wildcard include/config/x86/intel/umip.h) \ + $(wildcard include/config/x86/intel/memory/protection/keys.h) \ + $(wildcard include/config/page/table/isolation.h) \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/le.h \ + arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + $(wildcard include/config/cpu/big/endian.h) \ + include/uapi/linux/byteorder/little_endian.h \ + include/linux/swab.h \ + include/uapi/linux/swab.h \ + arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h \ + include/linux/log2.h \ + $(wildcard include/config/arch/has/ilog2/u32.h) \ + $(wildcard include/config/arch/has/ilog2/u64.h) \ + include/linux/typecheck.h \ + include/linux/printk.h \ + $(wildcard include/config/message/loglevel/default.h) \ + $(wildcard include/config/console/loglevel/default.h) \ + $(wildcard include/config/early/printk.h) \ + $(wildcard include/config/printk/nmi.h) \ + $(wildcard include/config/printk.h) \ + $(wildcard include/config/kmsg/ids.h) \ + $(wildcard include/config/dynamic/debug.h) \ + include/linux/init.h \ + $(wildcard include/config/strict/kernel/rwx.h) \ + $(wildcard include/config/strict/module/rwx.h) \ + include/linux/kern_levels.h \ + include/linux/cache.h \ + $(wildcard include/config/arch/has/cache/line/size.h) \ + include/uapi/linux/kernel.h \ + include/uapi/linux/sysinfo.h \ + include/uapi/linux/const.h \ + arch/x86/include/asm/cache.h \ + $(wildcard include/config/x86/l1/cache/shift.h) \ + $(wildcard include/config/x86/internode/cache/shift.h) \ + $(wildcard include/config/x86/vsmp.h) \ + include/linux/dynamic_debug.h \ + include/linux/build_bug.h \ + include/linux/mmzone.h \ + $(wildcard include/config/force/max/zoneorder.h) \ + $(wildcard include/config/zsmalloc.h) \ + $(wildcard include/config/sparsemem.h) \ + $(wildcard include/config/memory/hotplug.h) \ + $(wildcard include/config/discontigmem.h) \ + $(wildcard include/config/flat/node/mem/map.h) \ + $(wildcard include/config/page/extension.h) \ + $(wildcard include/config/no/bootmem.h) \ + $(wildcard include/config/numa/balancing.h) \ + $(wildcard include/config/deferred/struct/page/init.h) \ + $(wildcard include/config/transparent/hugepage.h) \ + $(wildcard include/config/have/memory/present.h) \ + $(wildcard include/config/have/memoryless/nodes.h) \ + $(wildcard include/config/need/node/memmap/size.h) \ + $(wildcard include/config/have/memblock/node/map.h) \ + $(wildcard include/config/need/multiple/nodes.h) \ + $(wildcard include/config/have/arch/early/pfn/to/nid.h) \ + $(wildcard include/config/flatmem.h) \ + $(wildcard include/config/sparsemem/extreme.h) \ + $(wildcard include/config/memory/hotremove.h) \ + $(wildcard include/config/have/arch/pfn/valid.h) \ + $(wildcard include/config/holes/in/zone.h) \ + $(wildcard include/config/arch/has/holes/memorymodel.h) \ + include/linux/spinlock.h \ + $(wildcard include/config/debug/spinlock.h) \ + $(wildcard include/config/preempt.h) \ + $(wildcard include/config/debug/lock/alloc.h) \ + include/linux/preempt.h \ + $(wildcard include/config/preempt/count.h) \ + $(wildcard include/config/debug/preempt.h) \ + $(wildcard include/config/preempt/tracer.h) \ + $(wildcard include/config/preempt/notifiers.h) \ + include/linux/list.h \ + $(wildcard include/config/debug/list.h) \ + include/linux/poison.h \ + $(wildcard include/config/illegal/pointer/value.h) \ + $(wildcard include/config/page/poisoning/zero.h) \ + arch/x86/include/asm/preempt.h \ + arch/x86/include/asm/percpu.h \ + $(wildcard include/config/x86/64/smp.h) \ + include/asm-generic/percpu.h \ + $(wildcard include/config/have/setup/per/cpu/area.h) \ + include/linux/threads.h \ + $(wildcard include/config/nr/cpus.h) \ + $(wildcard include/config/base/small.h) \ + include/linux/percpu-defs.h \ + $(wildcard include/config/debug/force/weak/per/cpu.h) \ + $(wildcard include/config/amd/mem/encrypt.h) \ + include/linux/thread_info.h \ + $(wildcard include/config/thread/info/in/task.h) \ + $(wildcard include/config/have/arch/within/stack/frames.h) \ + $(wildcard include/config/hardened/usercopy.h) \ + include/linux/restart_block.h \ + $(wildcard include/config/compat.h) \ + arch/x86/include/asm/current.h \ + arch/x86/include/asm/thread_info.h \ + $(wildcard include/config/vm86.h) \ + $(wildcard include/config/frame/pointer.h) \ + $(wildcard include/config/ia32/emulation.h) \ + arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_types.h \ + $(wildcard include/config/physical/start.h) \ + $(wildcard include/config/physical/align.h) \ + include/linux/mem_encrypt.h \ + $(wildcard include/config/arch/has/mem/encrypt.h) \ + arch/x86/include/asm/mem_encrypt.h \ + arch/x86/include/uapi/asm/bootparam.h \ + include/linux/screen_info.h \ + include/uapi/linux/screen_info.h \ + include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h \ + include/uapi/linux/ioctl.h \ + arch/x86/include/uapi/asm/ioctl.h \ + include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h \ + include/linux/edd.h \ + include/uapi/linux/edd.h \ + arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h \ + include/video/edid.h \ + $(wildcard include/config/x86.h) \ + include/uapi/video/edid.h \ + arch/x86/include/asm/page_64_types.h \ + $(wildcard include/config/kasan/extra.h) \ + $(wildcard include/config/randomize/memory.h) \ + $(wildcard include/config/randomize/base.h) \ + arch/x86/include/asm/kaslr.h \ + arch/x86/include/asm/page_64.h \ + $(wildcard include/config/x86/vsyscall/emulation.h) \ + include/linux/range.h \ + include/asm-generic/memory_model.h \ + $(wildcard include/config/sparsemem/vmemmap.h) \ + include/linux/pfn.h \ + include/asm-generic/getorder.h \ + arch/x86/include/asm/cpufeature.h \ + $(wildcard include/config/x86/feature/names.h) \ + $(wildcard include/config/x86/fast/feature/tests.h) \ + arch/x86/include/asm/processor.h \ + $(wildcard include/config/cc/stackprotector.h) \ + $(wildcard include/config/x86/debugctlmsr.h) \ + $(wildcard include/config/cpu/sup/amd.h) \ + $(wildcard include/config/xen.h) \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h \ + arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h \ + arch/x86/include/asm/segment.h \ + $(wildcard include/config/xen/pv.h) \ + $(wildcard include/config/x86/32/lazy/gs.h) \ + arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h \ + $(wildcard include/config/pgtable/levels.h) \ + $(wildcard include/config/paravirt/debug.h) \ + arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/kmap_types.h \ + $(wildcard include/config/debug/highmem.h) \ + include/asm-generic/kmap_types.h \ + arch/x86/include/asm/pgtable_types.h \ + $(wildcard include/config/mem/soft/dirty.h) \ + $(wildcard include/config/proc/fs.h) \ + arch/x86/include/asm/pgtable_64_types.h \ + arch/x86/include/asm/sparsemem.h \ + include/asm-generic/pgtable-nop4d.h \ + arch/x86/include/asm/nospec-branch.h \ + include/linux/static_key.h \ + arch/x86/include/asm/alternative-asm.h \ + arch/x86/include/asm/msr-index.h \ + $(wildcard include/config/control.h) \ + $(wildcard include/config/tdp/nominal.h) \ + $(wildcard include/config/tdp/level/1.h) \ + $(wildcard include/config/tdp/level/2.h) \ + $(wildcard include/config/tdp/control.h) \ + arch/x86/include/asm/spinlock_types.h \ + $(wildcard include/config/paravirt/spinlocks.h) \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h \ + include/asm-generic/ptrace.h \ + arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/msr.h \ + $(wildcard include/config/tracepoints.h) \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/cpumask.h \ + include/linux/cpumask.h \ + $(wildcard include/config/cpumask/offstack.h) \ + $(wildcard include/config/hotplug/cpu.h) \ + $(wildcard include/config/debug/per/cpu/maps.h) \ + include/linux/bitmap.h \ + arch/x86/include/uapi/asm/msr.h \ + arch/x86/include/asm/atomic.h \ + arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h \ + arch/x86/include/asm/atomic64_64.h \ + include/linux/tracepoint-defs.h \ + include/linux/atomic.h \ + $(wildcard include/config/generic/atomic64.h) \ + include/asm-generic/atomic-long.h \ + arch/x86/include/asm/paravirt.h \ + $(wildcard include/config/debug/entry.h) \ + arch/x86/include/asm/frame.h \ + arch/x86/include/asm/special_insns.h \ + arch/x86/include/asm/fpu/types.h \ + arch/x86/include/asm/unwind_hints.h \ + arch/x86/include/asm/orc_types.h \ + include/linux/personality.h \ + include/uapi/linux/personality.h \ + include/linux/math64.h \ + $(wildcard include/config/arch/supports/int128.h) \ + arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h \ + include/linux/err.h \ + include/linux/irqflags.h \ + $(wildcard include/config/trace/irqflags.h) \ + $(wildcard include/config/irqsoff/tracer.h) \ + $(wildcard include/config/trace/irqflags/support.h) \ + arch/x86/include/asm/irqflags.h \ + include/linux/bottom_half.h \ + include/linux/spinlock_types.h \ + include/linux/lockdep.h \ + $(wildcard include/config/lock/stat.h) \ + include/linux/rwlock_types.h \ + arch/x86/include/asm/spinlock.h \ + arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h \ + arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h \ + include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h \ + $(wildcard include/config/inline/spin/lock.h) \ + $(wildcard include/config/inline/spin/lock/bh.h) \ + $(wildcard include/config/inline/spin/lock/irq.h) \ + $(wildcard include/config/inline/spin/lock/irqsave.h) \ + $(wildcard include/config/inline/spin/trylock.h) \ + $(wildcard include/config/inline/spin/trylock/bh.h) \ + $(wildcard include/config/uninline/spin/unlock.h) \ + $(wildcard include/config/inline/spin/unlock/bh.h) \ + $(wildcard include/config/inline/spin/unlock/irq.h) \ + $(wildcard include/config/inline/spin/unlock/irqrestore.h) \ + $(wildcard include/config/generic/lockbreak.h) \ + include/linux/rwlock_api_smp.h \ + $(wildcard include/config/inline/read/lock.h) \ + $(wildcard include/config/inline/write/lock.h) \ + $(wildcard include/config/inline/read/lock/bh.h) \ + $(wildcard include/config/inline/write/lock/bh.h) \ + $(wildcard include/config/inline/read/lock/irq.h) \ + $(wildcard include/config/inline/write/lock/irq.h) \ + $(wildcard include/config/inline/read/lock/irqsave.h) \ + $(wildcard include/config/inline/write/lock/irqsave.h) \ + $(wildcard include/config/inline/read/trylock.h) \ + $(wildcard include/config/inline/write/trylock.h) \ + $(wildcard include/config/inline/read/unlock.h) \ + $(wildcard include/config/inline/write/unlock.h) \ + $(wildcard include/config/inline/read/unlock/bh.h) \ + $(wildcard include/config/inline/write/unlock/bh.h) \ + $(wildcard include/config/inline/read/unlock/irq.h) \ + $(wildcard include/config/inline/write/unlock/irq.h) \ + $(wildcard include/config/inline/read/unlock/irqrestore.h) \ + $(wildcard include/config/inline/write/unlock/irqrestore.h) \ + include/linux/wait.h \ + include/uapi/linux/wait.h \ + include/linux/numa.h \ + $(wildcard include/config/nodes/shift.h) \ + include/linux/seqlock.h \ + include/linux/nodemask.h \ + include/linux/pageblock-flags.h \ + $(wildcard include/config/hugetlb/page.h) \ + $(wildcard include/config/hugetlb/page/size/variable.h) \ + include/linux/page-flags-layout.h \ + include/generated/bounds.h \ + include/linux/memory_hotplug.h \ + $(wildcard include/config/arch/has/add/pages.h) \ + $(wildcard include/config/have/arch/nodedata/extension.h) \ + $(wildcard include/config/have/bootmem/info/node.h) \ + include/linux/notifier.h \ + include/linux/mutex.h \ + $(wildcard include/config/mutex/spin/on/owner.h) \ + $(wildcard include/config/debug/mutexes.h) \ + include/linux/osq_lock.h \ + include/linux/debug_locks.h \ + $(wildcard include/config/debug/locking/api/selftests.h) \ + include/linux/rwsem.h \ + $(wildcard include/config/rwsem/spin/on/owner.h) \ + $(wildcard include/config/rwsem/generic/spinlock.h) \ + arch/x86/include/asm/rwsem.h \ + include/linux/srcu.h \ + $(wildcard include/config/tiny/srcu.h) \ + $(wildcard include/config/tree/srcu.h) \ + $(wildcard include/config/srcu.h) \ + include/linux/rcupdate.h \ + $(wildcard include/config/preempt/rcu.h) \ + $(wildcard include/config/rcu/stall/common.h) \ + $(wildcard include/config/no/hz/full.h) \ + $(wildcard include/config/rcu/nocb/cpu.h) \ + $(wildcard include/config/tasks/rcu.h) \ + $(wildcard include/config/tree/rcu.h) \ + $(wildcard include/config/tiny/rcu.h) \ + $(wildcard include/config/debug/objects/rcu/head.h) \ + $(wildcard include/config/prove/rcu.h) \ + $(wildcard include/config/rcu/boost.h) \ + $(wildcard include/config/arch/weak/release/acquire.h) \ + include/linux/rcutree.h \ + include/linux/workqueue.h \ + $(wildcard include/config/debug/objects/work.h) \ + $(wildcard include/config/freezer.h) \ + $(wildcard include/config/sysfs.h) \ + $(wildcard include/config/wq/watchdog.h) \ + include/linux/timer.h \ + $(wildcard include/config/debug/objects/timers.h) \ + $(wildcard include/config/no/hz/common.h) \ + include/linux/ktime.h \ + include/linux/time.h \ + $(wildcard include/config/arch/uses/gettimeoffset.h) \ + include/linux/time64.h \ + include/uapi/linux/time.h \ + include/linux/time32.h \ + include/linux/jiffies.h \ + include/linux/timex.h \ + include/uapi/linux/timex.h \ + include/uapi/linux/param.h \ + arch/x86/include/uapi/asm/param.h \ + include/asm-generic/param.h \ + $(wildcard include/config/hz.h) \ + include/uapi/asm-generic/param.h \ + arch/x86/include/asm/timex.h \ + arch/x86/include/asm/tsc.h \ + $(wildcard include/config/x86/tsc.h) \ + include/generated/timeconst.h \ + include/linux/timekeeping.h \ + include/linux/timekeeping32.h \ + include/linux/debugobjects.h \ + $(wildcard include/config/debug/objects/free.h) \ + include/linux/rcu_segcblist.h \ + include/linux/srcutree.h \ + include/linux/rcu_node_tree.h \ + $(wildcard include/config/rcu/fanout.h) \ + $(wildcard include/config/rcu/fanout/leaf.h) \ + include/linux/completion.h \ + arch/x86/include/asm/mmzone.h \ + arch/x86/include/asm/mmzone_64.h \ + arch/x86/include/asm/smp.h \ + $(wildcard include/config/x86/local/apic.h) \ + $(wildcard include/config/x86/io/apic.h) \ + $(wildcard include/config/debug/nmi/selftest.h) \ + arch/x86/include/asm/mpspec.h \ + $(wildcard include/config/eisa.h) \ + $(wildcard include/config/x86/mpparse.h) \ + arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h \ + arch/x86/include/asm/apicdef.h \ + arch/x86/include/asm/apic.h \ + $(wildcard include/config/x86/x2apic.h) \ + arch/x86/include/asm/fixmap.h \ + $(wildcard include/config/provide/ohci1394/dma/init.h) \ + $(wildcard include/config/pci/mmconfig.h) \ + $(wildcard include/config/x86/intel/mid.h) \ + $(wildcard include/config/acpi/apei/ghes.h) \ + $(wildcard include/config/intel/txt.h) \ + arch/x86/include/asm/acpi.h \ + $(wildcard include/config/acpi/apei.h) \ + $(wildcard include/config/acpi.h) \ + $(wildcard include/config/acpi/numa.h) \ + include/acpi/pdc_intel.h \ + arch/x86/include/asm/numa.h \ + $(wildcard include/config/numa/emu.h) \ + arch/x86/include/asm/topology.h \ + $(wildcard include/config/sched/mc/prio.h) \ + include/asm-generic/topology.h \ + arch/x86/include/asm/mmu.h \ + $(wildcard include/config/modify/ldt/syscall.h) \ + arch/x86/include/asm/realmode.h \ + $(wildcard include/config/acpi/sleep.h) \ + arch/x86/include/asm/io.h \ + $(wildcard include/config/mtrr.h) \ + $(wildcard include/config/x86/pat.h) \ + arch/x86/include/generated/asm/early_ioremap.h \ + include/asm-generic/early_ioremap.h \ + $(wildcard include/config/generic/early/ioremap.h) \ + include/asm-generic/iomap.h \ + $(wildcard include/config/has/ioport/map.h) \ + $(wildcard include/config/pci.h) \ + $(wildcard include/config/generic/iomap.h) \ + include/asm-generic/pci_iomap.h \ + $(wildcard include/config/no/generic/pci/ioport/map.h) \ + $(wildcard include/config/generic/pci/iomap.h) \ + include/xen/xen.h \ + $(wildcard include/config/xen/pvh.h) \ + $(wildcard include/config/xen/dom0.h) \ + include/xen/interface/xen.h \ + arch/x86/include/asm/xen/interface.h \ + arch/x86/include/asm/xen/interface_64.h \ + arch/x86/include/asm/pvclock-abi.h \ + arch/x86/include/asm/xen/hypervisor.h \ + include/asm-generic/io.h \ + $(wildcard include/config/virt/to/bus.h) \ + include/linux/logic_pio.h \ + $(wildcard include/config/indirect/pio.h) \ + include/linux/fwnode.h \ + include/linux/vmalloc.h \ + include/linux/llist.h \ + $(wildcard include/config/arch/have/nmi/safe/cmpxchg.h) \ + include/linux/rbtree.h \ + arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h \ + arch/x86/include/asm/hardirq.h \ + $(wildcard include/config/kvm/intel.h) \ + $(wildcard include/config/have/kvm.h) \ + $(wildcard include/config/x86/thermal/vector.h) \ + $(wildcard include/config/x86/mce/threshold.h) \ + $(wildcard include/config/x86/mce/amd.h) \ + $(wildcard include/config/hyperv.h) \ + arch/x86/include/asm/io_apic.h \ + arch/x86/include/asm/irq_vectors.h \ + $(wildcard include/config/pci/msi.h) \ + include/linux/topology.h \ + $(wildcard include/config/use/percpu/numa/node/id.h) \ + $(wildcard include/config/sched/smt.h) \ + include/linux/smp.h \ + $(wildcard include/config/up/late/init.h) \ + include/linux/percpu.h \ + $(wildcard include/config/need/per/cpu/embed/first/chunk.h) \ + $(wildcard include/config/need/per/cpu/page/first/chunk.h) \ + include/linux/kmemleak.h \ + $(wildcard include/config/debug/kmemleak.h) \ + include/linux/kasan.h \ + include/linux/socket.h \ + arch/x86/include/uapi/asm/socket.h \ + include/uapi/asm-generic/socket.h \ + arch/x86/include/uapi/asm/sockios.h \ + include/uapi/asm-generic/sockios.h \ + include/uapi/linux/sockios.h \ + include/linux/uio.h \ + include/uapi/linux/uio.h \ + include/uapi/linux/socket.h \ + /data/libkernelsepol/libsepol/src/private.h \ + /data/libkernelsepol/libsepol/src/mls.h \ + /data/libkernelsepol/libsepol/src/policydb_internal.h \ + +/data/libkernelsepol/libsepol/src/write.o: $(deps_/data/libkernelsepol/libsepol/src/write.o) + +$(deps_/data/libkernelsepol/libsepol/src/write.o): diff --git a/kernel/libsepol/src/Makefile b/kernel/libsepol/src/Makefile new file mode 100644 index 00000000..13410c67 --- /dev/null +++ b/kernel/libsepol/src/Makefile @@ -0,0 +1,104 @@ +# Installation directories. +PREFIX ?= /usr +INCLUDEDIR ?= $(PREFIX)/include +LIBDIR ?= $(PREFIX)/lib +SHLIBDIR ?= /lib +RANLIB ?= ranlib +CILDIR ?= ../cil + +VERSION = $(shell cat ../VERSION) +LIBVERSION = 2 + +LEX = flex +CIL_GENERATED = $(CILDIR)/src/cil_lexer.c + +LIBA=libsepol.a +TARGET=libsepol.so +LIBPC=libsepol.pc +LIBMAP=libsepol.map +LIBSO=$(TARGET).$(LIBVERSION) +OBJS= $(patsubst %.c,%.o,$(sort $(wildcard *.c))) +LOBJS= $(patsubst %.c,%.lo,$(sort $(wildcard *.c))) +CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-format-attribute -O2 -fno-semantic-interposition + +override CFLAGS += -I. -I../include -D_GNU_SOURCE + +ifneq ($(DISABLE_CIL),y) +OBJS += $(sort $(patsubst %.c,%.o,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED))) +LOBJS += $(sort $(patsubst %.c,%.lo,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED))) +override CFLAGS += -I$(CILDIR)/include +endif + +# check for reallocarray(3) availability +H := \# +ifeq (yes,$(shell printf '${H}define _GNU_SOURCE\n${H}include \nint main(void){void*p=reallocarray(NULL, 1, sizeof(char));return 0;}' | $(CC) -x c -o /dev/null - >/dev/null 2>&1 && echo yes)) +override CFLAGS += -DHAVE_REALLOCARRAY +endif + +LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=$(LIBMAP),-z,defs + +LN=ln +OS := $(shell uname) +ifeq ($(OS), Darwin) +LD_SONAME_FLAGS=-install_name,$(LIBSO) +LDFLAGS += -undefined dynamic_lookup +LN=gln +endif + +all: $(LIBA) $(LIBSO) $(LIBPC) + + +$(LIBA): $(OBJS) + $(AR) rcs $@ $^ + $(RANLIB) $@ + +$(LIBSO): $(LOBJS) $(LIBMAP) + $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(LOBJS) -Wl,$(LD_SONAME_FLAGS) + ln -sf $@ $(TARGET) + +$(LIBPC): $(LIBPC).in ../VERSION + sed -e 's/@VERSION@/$(VERSION)/; s:@prefix@:$(PREFIX):; s:@libdir@:$(LIBDIR):; s:@includedir@:$(INCLUDEDIR):' < $< > $@ + +$(LIBMAP): $(LIBMAP).in +ifneq ($(DISABLE_CIL),y) + cp $< $@ +else + sed -e '/^\s*cil_/d' < $< > $@ +endif + +ifneq ($(DISABLE_CIL),y) +$(CILDIR)/src/cil_lexer.o: $(CILDIR)/src/cil_lexer.c + $(CC) $(filter-out -Werror, $(CFLAGS)) -fPIC -c -o $@ $< + +$(CILDIR)/src/cil_lexer.lo: $(CILDIR)/src/cil_lexer.c + $(CC) $(filter-out -Werror, $(CFLAGS)) -fPIC -DSHARED -c -o $@ $< + +$(CILDIR)/src/cil_lexer.c: $(CILDIR)/src/cil_lexer.l + $(LEX) -o $@ $< + +endif + +%.o: %.c + $(CC) $(CFLAGS) -fPIC -c -o $@ $< + +%.lo: %.c + $(CC) $(CFLAGS) -fPIC -DSHARED -c -o $@ $< + +install: all + test -d $(DESTDIR)$(LIBDIR) || install -m 755 -d $(DESTDIR)$(LIBDIR) + install -m 644 $(LIBA) $(DESTDIR)$(LIBDIR) + test -d $(DESTDIR)$(SHLIBDIR) || install -m 755 -d $(DESTDIR)$(SHLIBDIR) + install -m 755 $(LIBSO) $(DESTDIR)$(SHLIBDIR) + test -d $(DESTDIR)$(LIBDIR)/pkgconfig || install -m 755 -d $(DESTDIR)$(LIBDIR)/pkgconfig + install -m 644 $(LIBPC) $(DESTDIR)$(LIBDIR)/pkgconfig + $(LN) -sf --relative $(DESTDIR)$(SHLIBDIR)/$(LIBSO) $(DESTDIR)$(LIBDIR)/$(TARGET) + +relabel: + /sbin/restorecon $(DESTDIR)$(SHLIBDIR)/$(LIBSO) + +clean: + -rm -f $(LIBPC) $(LIBMAP) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(CIL_GENERATED) + +indent: + ../../scripts/Lindent $(wildcard *.[ch]) + diff --git a/kernel/libsepol/src/Makefile2 b/kernel/libsepol/src/Makefile2 new file mode 100644 index 00000000..13410c67 --- /dev/null +++ b/kernel/libsepol/src/Makefile2 @@ -0,0 +1,104 @@ +# Installation directories. +PREFIX ?= /usr +INCLUDEDIR ?= $(PREFIX)/include +LIBDIR ?= $(PREFIX)/lib +SHLIBDIR ?= /lib +RANLIB ?= ranlib +CILDIR ?= ../cil + +VERSION = $(shell cat ../VERSION) +LIBVERSION = 2 + +LEX = flex +CIL_GENERATED = $(CILDIR)/src/cil_lexer.c + +LIBA=libsepol.a +TARGET=libsepol.so +LIBPC=libsepol.pc +LIBMAP=libsepol.map +LIBSO=$(TARGET).$(LIBVERSION) +OBJS= $(patsubst %.c,%.o,$(sort $(wildcard *.c))) +LOBJS= $(patsubst %.c,%.lo,$(sort $(wildcard *.c))) +CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-format-attribute -O2 -fno-semantic-interposition + +override CFLAGS += -I. -I../include -D_GNU_SOURCE + +ifneq ($(DISABLE_CIL),y) +OBJS += $(sort $(patsubst %.c,%.o,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED))) +LOBJS += $(sort $(patsubst %.c,%.lo,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED))) +override CFLAGS += -I$(CILDIR)/include +endif + +# check for reallocarray(3) availability +H := \# +ifeq (yes,$(shell printf '${H}define _GNU_SOURCE\n${H}include \nint main(void){void*p=reallocarray(NULL, 1, sizeof(char));return 0;}' | $(CC) -x c -o /dev/null - >/dev/null 2>&1 && echo yes)) +override CFLAGS += -DHAVE_REALLOCARRAY +endif + +LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=$(LIBMAP),-z,defs + +LN=ln +OS := $(shell uname) +ifeq ($(OS), Darwin) +LD_SONAME_FLAGS=-install_name,$(LIBSO) +LDFLAGS += -undefined dynamic_lookup +LN=gln +endif + +all: $(LIBA) $(LIBSO) $(LIBPC) + + +$(LIBA): $(OBJS) + $(AR) rcs $@ $^ + $(RANLIB) $@ + +$(LIBSO): $(LOBJS) $(LIBMAP) + $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(LOBJS) -Wl,$(LD_SONAME_FLAGS) + ln -sf $@ $(TARGET) + +$(LIBPC): $(LIBPC).in ../VERSION + sed -e 's/@VERSION@/$(VERSION)/; s:@prefix@:$(PREFIX):; s:@libdir@:$(LIBDIR):; s:@includedir@:$(INCLUDEDIR):' < $< > $@ + +$(LIBMAP): $(LIBMAP).in +ifneq ($(DISABLE_CIL),y) + cp $< $@ +else + sed -e '/^\s*cil_/d' < $< > $@ +endif + +ifneq ($(DISABLE_CIL),y) +$(CILDIR)/src/cil_lexer.o: $(CILDIR)/src/cil_lexer.c + $(CC) $(filter-out -Werror, $(CFLAGS)) -fPIC -c -o $@ $< + +$(CILDIR)/src/cil_lexer.lo: $(CILDIR)/src/cil_lexer.c + $(CC) $(filter-out -Werror, $(CFLAGS)) -fPIC -DSHARED -c -o $@ $< + +$(CILDIR)/src/cil_lexer.c: $(CILDIR)/src/cil_lexer.l + $(LEX) -o $@ $< + +endif + +%.o: %.c + $(CC) $(CFLAGS) -fPIC -c -o $@ $< + +%.lo: %.c + $(CC) $(CFLAGS) -fPIC -DSHARED -c -o $@ $< + +install: all + test -d $(DESTDIR)$(LIBDIR) || install -m 755 -d $(DESTDIR)$(LIBDIR) + install -m 644 $(LIBA) $(DESTDIR)$(LIBDIR) + test -d $(DESTDIR)$(SHLIBDIR) || install -m 755 -d $(DESTDIR)$(SHLIBDIR) + install -m 755 $(LIBSO) $(DESTDIR)$(SHLIBDIR) + test -d $(DESTDIR)$(LIBDIR)/pkgconfig || install -m 755 -d $(DESTDIR)$(LIBDIR)/pkgconfig + install -m 644 $(LIBPC) $(DESTDIR)$(LIBDIR)/pkgconfig + $(LN) -sf --relative $(DESTDIR)$(SHLIBDIR)/$(LIBSO) $(DESTDIR)$(LIBDIR)/$(TARGET) + +relabel: + /sbin/restorecon $(DESTDIR)$(SHLIBDIR)/$(LIBSO) + +clean: + -rm -f $(LIBPC) $(LIBMAP) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(CIL_GENERATED) + +indent: + ../../scripts/Lindent $(wildcard *.[ch]) + diff --git a/kernel/libsepol/src/assertion.c b/kernel/libsepol/src/assertion.c new file mode 100644 index 00000000..2044c02e --- /dev/null +++ b/kernel/libsepol/src/assertion.c @@ -0,0 +1,574 @@ +/* Authors: Joshua Brindle + * + * Assertion checker for avtab entries, taken from + * checkpolicy.c by Stephen Smalley + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include "private.h" +#include "debug.h" + +struct avtab_match_args { + sepol_handle_t *handle; + policydb_t *p; + avrule_t *avrule; + avtab_t *avtab; + unsigned long errors; +}; + +static const char* policy_name(policydb_t *p) { + const char *policy_file = "policy.conf"; + if (p->name) { + policy_file = p->name; + } + return policy_file; +} + +static void report_failure(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule, + unsigned int stype, unsigned int ttype, + const class_perm_node_t *curperm, uint32_t perms) +{ + if (avrule->source_filename) { + ERR(handle, "neverallow on line %lu of %s (or line %lu of %s) violated by allow %s %s:%s {%s };", + avrule->source_line, avrule->source_filename, avrule->line, policy_name(p), + p->p_type_val_to_name[stype], + p->p_type_val_to_name[ttype], + p->p_class_val_to_name[curperm->tclass - 1], + sepol_av_to_string(p, curperm->tclass, perms)); + } else if (avrule->line) { + ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };", + avrule->line, p->p_type_val_to_name[stype], + p->p_type_val_to_name[ttype], + p->p_class_val_to_name[curperm->tclass - 1], + sepol_av_to_string(p, curperm->tclass, perms)); + } else { + ERR(handle, "neverallow violated by allow %s %s:%s {%s };", + p->p_type_val_to_name[stype], + p->p_type_val_to_name[ttype], + p->p_class_val_to_name[curperm->tclass - 1], + sepol_av_to_string(p, curperm->tclass, perms)); + } +} + +static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, uint32_t data) +{ + for (; cp; cp = cp->next) { + if ((cp->tclass == class) && (cp->data & data)) + return 1; + } + + return 0; +} + +static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) { + size_t i; + for (i = 0; i < EXTENDED_PERMS_LEN; i++) { + if (perms1[i] & perms2[i]) + return 1; + } + + return 0; +} + +static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow) +{ + int rc = 0; + if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION) + && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) { + if (neverallow->driver == allow->driver) + rc = extended_permissions_and(neverallow->perms, allow->perms); + } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION) + && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) { + rc = xperm_test(neverallow->driver, allow->perms); + } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER) + && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) { + rc = xperm_test(allow->driver, neverallow->perms); + } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER) + && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) { + rc = extended_permissions_and(neverallow->perms, allow->perms); + } + + return rc; +} + +/* Compute which allowed extended permissions violate the neverallow rule */ +static void extended_permissions_violated(avtab_extended_perms_t *result, + av_extended_perms_t *neverallow, + avtab_extended_perms_t *allow) +{ + size_t i; + if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION) + && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) { + result->specified = AVTAB_XPERMS_IOCTLFUNCTION; + result->driver = allow->driver; + for (i = 0; i < EXTENDED_PERMS_LEN; i++) + result->perms[i] = neverallow->perms[i] & allow->perms[i]; + } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION) + && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) { + result->specified = AVTAB_XPERMS_IOCTLFUNCTION; + result->driver = neverallow->driver; + memcpy(result->perms, neverallow->perms, sizeof(result->perms)); + } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER) + && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) { + result->specified = AVTAB_XPERMS_IOCTLFUNCTION; + result->driver = allow->driver; + memcpy(result->perms, allow->perms, sizeof(result->perms)); + } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER) + && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) { + result->specified = AVTAB_XPERMS_IOCTLDRIVER; + for (i = 0; i < EXTENDED_PERMS_LEN; i++) + result->perms[i] = neverallow->perms[i] & allow->perms[i]; + } +} + +/* Same scenarios of interest as check_assertion_extended_permissions */ +static int report_assertion_extended_permissions(sepol_handle_t *handle, + policydb_t *p, const avrule_t *avrule, + unsigned int stype, unsigned int ttype, + const class_perm_node_t *curperm, uint32_t perms, + avtab_key_t *k, avtab_t *avtab) +{ + avtab_ptr_t node; + avtab_key_t tmp_key; + avtab_extended_perms_t *xperms; + avtab_extended_perms_t error; + ebitmap_t *sattr = &p->type_attr_map[stype]; + ebitmap_t *tattr = &p->type_attr_map[ttype]; + ebitmap_node_t *snode, *tnode; + unsigned int i, j; + int rc; + int found_xperm = 0; + int errors = 0; + + memcpy(&tmp_key, k, sizeof(avtab_key_t)); + tmp_key.specified = AVTAB_XPERMS_ALLOWED; + + ebitmap_for_each_positive_bit(sattr, snode, i) { + tmp_key.source_type = i + 1; + ebitmap_for_each_positive_bit(tattr, tnode, j) { + tmp_key.target_type = j + 1; + for (node = ksu_avtab_search_node(avtab, &tmp_key); + node; + node = ksu_avtab_search_node_next(node, tmp_key.specified)) { + xperms = node->datum.xperms; + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) + continue; + found_xperm = 1; + rc = check_extended_permissions(avrule->xperms, xperms); + /* failure on the extended permission check_extended_permissions */ + if (rc) { + extended_permissions_violated(&error, avrule->xperms, xperms); + ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" + "allowxperm %s %s:%s %s;", + avrule->source_line, avrule->source_filename, avrule->line, policy_name(p), + p->p_type_val_to_name[i], + p->p_type_val_to_name[j], + p->p_class_val_to_name[curperm->tclass - 1], + sepol_extended_perms_to_string(&error)); + + errors++; + } + } + } + } + + /* failure on the regular permissions */ + if (!found_xperm) { + ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" + "allow %s %s:%s {%s };", + avrule->source_line, avrule->source_filename, avrule->line, policy_name(p), + p->p_type_val_to_name[stype], + p->p_type_val_to_name[ttype], + p->p_class_val_to_name[curperm->tclass - 1], + sepol_av_to_string(p, curperm->tclass, perms)); + errors++; + + } + + return errors; +} + +static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args) +{ + int rc = 0; + struct avtab_match_args *a = (struct avtab_match_args *)args; + sepol_handle_t *handle = a->handle; + policydb_t *p = a->p; + avtab_t *avtab = a->avtab; + avrule_t *avrule = a->avrule; + class_perm_node_t *cp; + uint32_t perms; + ebitmap_t src_matches, tgt_matches, self_matches; + ebitmap_node_t *snode, *tnode; + unsigned int i, j; + const int is_avrule_self = (avrule->flags & RULE_SELF) != 0; + + if ((k->specified & AVTAB_ALLOWED) == 0) + return 0; + + if (!match_any_class_permissions(avrule->perms, k->target_class, d->data)) + return 0; + + ebitmap_init(&src_matches); + ebitmap_init(&tgt_matches); + ebitmap_init(&self_matches); + + rc = ksu_ebitmap_and(&src_matches, &avrule->stypes.types, + &p->attr_type_map[k->source_type - 1]); + if (rc < 0) + goto oom; + + if (ebitmap_is_empty(&src_matches)) + goto exit; + + rc = ksu_ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]); + if (rc < 0) + goto oom; + + if (is_avrule_self) { + rc = ksu_ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]); + if (rc < 0) + goto oom; + + if (!ebitmap_is_empty(&self_matches)) { + rc = ebitmap_union(&tgt_matches, &self_matches); + if (rc < 0) + goto oom; + } + } + + if (ebitmap_is_empty(&tgt_matches)) + goto exit; + + for (cp = avrule->perms; cp; cp = cp->next) { + + perms = cp->data & d->data; + if ((cp->tclass != k->target_class) || !perms) { + continue; + } + + ebitmap_for_each_positive_bit(&src_matches, snode, i) { + ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) { + if (is_avrule_self && i != j) + continue; + if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) { + a->errors += report_assertion_extended_permissions(handle,p, avrule, + i, j, cp, perms, k, avtab); + } else { + a->errors++; + report_failure(handle, p, avrule, i, j, cp, perms); + } + } + } + } + +oom: +exit: + ksu_ebitmap_destroy(&src_matches); + ksu_ebitmap_destroy(&tgt_matches); + ksu_ebitmap_destroy(&self_matches); + return rc; +} + +static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule) +{ + int rc; + struct avtab_match_args args; + + args.handle = handle; + args.p = p; + args.avrule = avrule; + args.errors = 0; + + args.avtab = &p->te_avtab; + rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args); + if (rc < 0) + goto oom; + + args.avtab = &p->te_cond_avtab; + rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args); + if (rc < 0) + goto oom; + + return args.errors; + +oom: + return rc; +} + +/* + * Look up the extended permissions in avtab and verify that neverallowed + * permissions are not granted. + */ +static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab, + unsigned int stype, unsigned int ttype, + avtab_key_t *k, policydb_t *p) +{ + avtab_ptr_t node; + avtab_key_t tmp_key; + avtab_extended_perms_t *xperms; + av_extended_perms_t *neverallow_xperms = avrule->xperms; + ebitmap_t *sattr = &p->type_attr_map[stype]; + ebitmap_t *tattr = &p->type_attr_map[ttype]; + ebitmap_node_t *snode, *tnode; + unsigned int i, j; + int rc = 1; + + memcpy(&tmp_key, k, sizeof(avtab_key_t)); + tmp_key.specified = AVTAB_XPERMS_ALLOWED; + + ebitmap_for_each_positive_bit(sattr, snode, i) { + tmp_key.source_type = i + 1; + ebitmap_for_each_positive_bit(tattr, tnode, j) { + tmp_key.target_type = j + 1; + for (node = ksu_avtab_search_node(avtab, &tmp_key); + node; + node = ksu_avtab_search_node_next(node, tmp_key.specified)) { + xperms = node->datum.xperms; + + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) + continue; + rc = check_extended_permissions(neverallow_xperms, xperms); + if (rc) + return rc; + } + } + } + + return rc; +} + +/* + * When the ioctl permission is granted on an avtab entry that matches an + * avrule neverallowxperm entry, enumerate over the matching + * source/target/class sets to determine if the extended permissions exist + * and if the neverallowed ioctls are granted. + * + * Four scenarios of interest: + * 1. PASS - the ioctl permission is not granted for this source/target/class + * This case is handled in check_assertion_avtab_match + * 2. PASS - The ioctl permission is granted AND the extended permission + * is NOT granted + * 3. FAIL - The ioctl permission is granted AND no extended permissions + * exist + * 4. FAIL - The ioctl permission is granted AND the extended permission is + * granted + */ +static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab, + avtab_key_t *k, policydb_t *p) +{ + ebitmap_t src_matches, tgt_matches, self_matches; + unsigned int i, j; + ebitmap_node_t *snode, *tnode; + const int is_avrule_self = (avrule->flags & RULE_SELF) != 0; + int rc; + + ebitmap_init(&src_matches); + ebitmap_init(&tgt_matches); + ebitmap_init(&self_matches); + + rc = ksu_ebitmap_and(&src_matches, &avrule->stypes.types, + &p->attr_type_map[k->source_type - 1]); + if (rc < 0) + goto oom; + + if (ebitmap_is_empty(&src_matches)) { + rc = 0; + goto exit; + } + + rc = ksu_ebitmap_and(&tgt_matches, &avrule->ttypes.types, + &p->attr_type_map[k->target_type -1]); + if (rc < 0) + goto oom; + + if (is_avrule_self) { + rc = ksu_ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]); + if (rc < 0) + goto oom; + + if (!ebitmap_is_empty(&self_matches)) { + rc = ebitmap_union(&tgt_matches, &self_matches); + if (rc < 0) + goto oom; + } + } + + if (ebitmap_is_empty(&tgt_matches)) { + rc = 0; + goto exit; + } + + ebitmap_for_each_positive_bit(&src_matches, snode, i) { + ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) { + if (is_avrule_self && i != j) + continue; + if (check_assertion_extended_permissions_avtab(avrule, avtab, i, j, k, p)) { + rc = 1; + goto exit; + } + } + } + + rc = 0; + +oom: +exit: + ksu_ebitmap_destroy(&src_matches); + ksu_ebitmap_destroy(&tgt_matches); + ksu_ebitmap_destroy(&self_matches); + return rc; +} + +static int check_assertion_self_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p) +{ + ebitmap_t src_matches; + int rc; + + /* The key's target must match something in the matches of the avrule's source + * and the key's source. + */ + + rc = ksu_ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]); + if (rc < 0) + goto oom; + + if (!ebitmap_match_any(&src_matches, &p->attr_type_map[k->target_type - 1])) { + rc = 0; + goto nomatch; + } + + rc = 1; + +oom: +nomatch: + ksu_ebitmap_destroy(&src_matches); + return rc; +} + +static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args) +{ + int rc; + struct avtab_match_args *a = (struct avtab_match_args *)args; + policydb_t *p = a->p; + avrule_t *avrule = a->avrule; + avtab_t *avtab = a->avtab; + + if ((k->specified & AVTAB_ALLOWED) == 0) + goto nomatch; + + if (!match_any_class_permissions(avrule->perms, k->target_class, d->data)) + goto nomatch; + + if (!ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1])) + goto nomatch; + + /* neverallow may have tgts even if it uses SELF */ + if (!ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1])) { + if (avrule->flags == RULE_SELF) { + rc = check_assertion_self_match(k, avrule, p); + if (rc < 0) + goto oom; + if (rc == 0) + goto nomatch; + } else { + goto nomatch; + } + } + + if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) { + rc = check_assertion_extended_permissions(avrule, avtab, k, p); + if (rc < 0) + goto oom; + if (rc == 0) + goto nomatch; + } + return 1; + +nomatch: + return 0; + +oom: + return rc; +} + +int check_assertion(policydb_t *p, avrule_t *avrule) +{ + int rc; + struct avtab_match_args args; + + args.handle = NULL; + args.p = p; + args.avrule = avrule; + args.errors = 0; + args.avtab = &p->te_avtab; + + rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args); + + if (rc == 0) { + args.avtab = &p->te_cond_avtab; + rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args); + } + + return rc; +} + +int check_assertions(sepol_handle_t * handle, policydb_t * p, + avrule_t * avrules) +{ + int rc; + avrule_t *a; + unsigned long errors = 0; + + if (!avrules) { + /* Since assertions are stored in avrules, if it is NULL + there won't be any to check. This also prevents an invalid + free if the avtabs are never initialized */ + return 0; + } + + for (a = avrules; a != NULL; a = a->next) { + if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW))) + continue; + rc = check_assertion(p, a); + if (rc < 0) { + ERR(handle, "Error occurred while checking neverallows"); + return -1; + } + if (rc) { + rc = report_assertion_failures(handle, p, a); + if (rc < 0) { + ERR(handle, "Error occurred while checking neverallows"); + return -1; + } + errors += rc; + } + } + + if (errors) + ERR(handle, "%lu neverallow failures occurred", errors); + + return errors ? -1 : 0; +} diff --git a/kernel/libsepol/src/assertion.o b/kernel/libsepol/src/assertion.o new file mode 100644 index 00000000..cb8616ee Binary files /dev/null and b/kernel/libsepol/src/assertion.o differ diff --git a/kernel/libsepol/src/avrule_block.c b/kernel/libsepol/src/avrule_block.c new file mode 100644 index 00000000..216cae3b --- /dev/null +++ b/kernel/libsepol/src/avrule_block.c @@ -0,0 +1,220 @@ +/* Authors: Jason Tang + * + * Functions that manipulate a logical block (conditional, optional, + * or global scope) for a policy module. + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +// #include +// #include +#include "kernel.h" + +/* It is anticipated that there be less declarations within an avrule + * block than the global policy. Thus the symbol table sizes are + * smaller than those listed in policydb.c */ +static const unsigned int symtab_sizes[SYM_NUM] = { + 2, + 4, + 8, + 32, + 16, + 4, + 2, + 2, +}; + +avrule_block_t *avrule_block_create(void) +{ + avrule_block_t *block; + if ((block = calloc(1, sizeof(*block))) == NULL) { + return NULL; + } + return block; +} + +avrule_decl_t *avrule_decl_create(uint32_t decl_id) +{ + avrule_decl_t *decl; + int i; + if ((decl = calloc(1, sizeof(*decl))) == NULL) { + return NULL; + } + decl->decl_id = decl_id; + for (i = 0; i < SYM_NUM; i++) { + if (ksu_symtab_init(&decl->symtab[i], symtab_sizes[i])) { + avrule_decl_destroy(decl); + return NULL; + } + } + + for (i = 0; i < SYM_NUM; i++) { + ebitmap_init(&decl->required.scope[i]); + ebitmap_init(&decl->declared.scope[i]); + } + return decl; +} + +/* note that unlike the other destroy functions, this one does /NOT/ + * destroy the pointer itself */ +static void scope_index_destroy(scope_index_t * scope) +{ + unsigned int i; + if (scope == NULL) { + return; + } + for (i = 0; i < SYM_NUM; i++) { + ksu_ebitmap_destroy(scope->scope + i); + } + if (scope->class_perms_map) { + for (i = 0; i < scope->class_perms_len; i++) { + ksu_ebitmap_destroy(scope->class_perms_map + i); + } + } + free(scope->class_perms_map); +} + +void avrule_decl_destroy(avrule_decl_t * x) +{ + if (x == NULL) { + return; + } + cond_list_destroy(x->cond_list); + avrule_list_destroy(x->avrules); + role_trans_rule_list_destroy(x->role_tr_rules); + filename_trans_rule_list_destroy(x->filename_trans_rules); + role_allow_rule_list_destroy(x->role_allow_rules); + range_trans_rule_list_destroy(x->range_tr_rules); + scope_index_destroy(&x->required); + scope_index_destroy(&x->declared); + symtabs_destroy(x->symtab); + free(x->module_name); + free(x); +} + +void avrule_block_destroy(avrule_block_t * x) +{ + avrule_decl_t *decl; + if (x == NULL) { + return; + } + decl = x->branch_list; + while (decl != NULL) { + avrule_decl_t *next_decl = decl->next; + avrule_decl_destroy(decl); + decl = next_decl; + } + free(x); +} + +void avrule_block_list_destroy(avrule_block_t * x) +{ + while (x != NULL) { + avrule_block_t *next = x->next; + avrule_block_destroy(x); + x = next; + } +} + +/* Get a conditional node from a avrule_decl with the same expression. + * If that expression does not exist then create one. */ +cond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl, + cond_list_t * cond) +{ + cond_list_t *result; + int was_created; + result = cond_node_find(p, cond, decl->cond_list, &was_created); + if (result != NULL && was_created) { + result->next = decl->cond_list; + decl->cond_list = result; + } + return result; +} + +/* Look up an identifier in a policy's scoping table. If it is there, + * marked as SCOPE_DECL, and any of its declaring block has been enabled, + * then return 1. Otherwise return 0. Can only be called after the + * decl_val_to_struct index has been created */ +int is_id_enabled(char *id, policydb_t * p, int symbol_table) +{ + scope_datum_t *scope = + (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id); + avrule_decl_t *decl; + uint32_t len; + + if (scope == NULL) { + return 0; + } + if (scope->scope != SCOPE_DECL) { + return 0; + } + + len = scope->decl_ids_len; + if (len < 1) { + return 0; + } + + if (symbol_table == SYM_ROLES || symbol_table == SYM_USERS) { + uint32_t i; + for (i = 0; i < len; i++) { + decl = p->decl_val_to_struct[scope->decl_ids[i] - 1]; + if (decl != NULL && decl->enabled) { + return 1; + } + } + } else { + decl = p->decl_val_to_struct[scope->decl_ids[len-1] - 1]; + if (decl != NULL && decl->enabled) { + return 1; + } + } + + return 0; +} + +/* Check if a particular permission is present within the given class, + * and that the class is enabled. Returns 1 if both conditions are + * true, 0 if neither could be found or if the class id disabled. */ +int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p) +{ + class_datum_t *cladatum; + perm_datum_t *perm; + if (!is_id_enabled(class_id, p, SYM_CLASSES)) { + return 0; + } + cladatum = + (class_datum_t *) hashtab_search(p->p_classes.table, class_id); + if (cladatum == NULL) { + return 0; + } + perm = hashtab_search(cladatum->permissions.table, perm_id); + if (perm == NULL && cladatum->comdatum != 0) { + /* permission was not in this class. before giving + * up, check the class's parent */ + perm = + hashtab_search(cladatum->comdatum->permissions.table, + perm_id); + } + if (perm == NULL) { + return 0; + } + return 1; +} diff --git a/kernel/libsepol/src/avrule_block.o b/kernel/libsepol/src/avrule_block.o new file mode 100644 index 00000000..67cf16da Binary files /dev/null and b/kernel/libsepol/src/avrule_block.o differ diff --git a/kernel/libsepol/src/avtab.c b/kernel/libsepol/src/avtab.c new file mode 100644 index 00000000..ca2d537e --- /dev/null +++ b/kernel/libsepol/src/avtab.c @@ -0,0 +1,633 @@ + +/* Author : Stephen Smalley, */ + +/* + * Updated: Yuichi Nakamura + * Tuned number of hash slots for avtab to reduce memory usage + */ + +/* Updated: Frank Mayer + * and Karl MacMillan + * + * Added conditional policy language extensions + * + * Updated: Red Hat, Inc. James Morris + * + * Code cleanup + * + * Updated: Karl MacMillan + * + * Copyright (C) 2003 Tresys Technology, LLC + * Copyright (C) 2003,2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * Implementation of the access vector table type. + */ + +// #include +#include +#include +#include + +#include "debug.h" +#include "private.h" +#include "kernel.h" + +/* Based on MurmurHash3, written by Austin Appleby and placed in the + * public domain. + */ +ignore_unsigned_overflow_ +static inline int avtab_hash(struct avtab_key *keyp, uint32_t mask) +{ + static const uint32_t c1 = 0xcc9e2d51; + static const uint32_t c2 = 0x1b873593; + static const uint32_t r1 = 15; + static const uint32_t r2 = 13; + static const uint32_t m = 5; + static const uint32_t n = 0xe6546b64; + + uint32_t hash = 0; + +#define mix(input) do { \ + uint32_t v = input; \ + v *= c1; \ + v = (v << r1) | (v >> (32 - r1)); \ + v *= c2; \ + hash ^= v; \ + hash = (hash << r2) | (hash >> (32 - r2)); \ + hash = hash * m + n; \ +} while (0) + + mix(keyp->target_class); + mix(keyp->target_type); + mix(keyp->source_type); + +#undef mix + + hash ^= hash >> 16; + hash *= 0x85ebca6b; + hash ^= hash >> 13; + hash *= 0xc2b2ae35; + hash ^= hash >> 16; + + return hash & mask; +} + +static avtab_ptr_t +avtab_insert_node(avtab_t * h, int hvalue, avtab_ptr_t prev, avtab_key_t * key, + avtab_datum_t * datum) +{ + avtab_ptr_t newnode; + avtab_extended_perms_t *xperms; + + newnode = (avtab_ptr_t) malloc(sizeof(struct avtab_node)); + if (newnode == NULL) + return NULL; + memset(newnode, 0, sizeof(struct avtab_node)); + newnode->key = *key; + + if (key->specified & AVTAB_XPERMS) { + xperms = calloc(1, sizeof(avtab_extended_perms_t)); + if (xperms == NULL) { + free(newnode); + return NULL; + } + if (datum->xperms) /* else caller populates xperms */ + *xperms = *(datum->xperms); + + newnode->datum.xperms = xperms; + /* data is usually ignored with xperms, except in the case of + * neverallow checking, which requires permission bits to be set. + * So copy data so it is set in the avtab + */ + newnode->datum.data = datum->data; + } else { + newnode->datum = *datum; + } + + if (prev) { + newnode->next = prev->next; + prev->next = newnode; + } else { + newnode->next = h->htable[hvalue]; + h->htable[hvalue] = newnode; + } + + h->nel++; + return newnode; +} + +int avtab_insert(avtab_t * h, avtab_key_t * key, avtab_datum_t * datum) +{ + int hvalue; + avtab_ptr_t prev, cur, newnode; + uint16_t specified = + key->specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD); + + if (!h || !h->htable) + return SEPOL_ENOMEM; + + hvalue = avtab_hash(key, h->mask); + for (prev = NULL, cur = h->htable[hvalue]; + cur; prev = cur, cur = cur->next) { + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class == cur->key.target_class && + (specified & cur->key.specified)) { + /* Extended permissions are not necessarily unique */ + if (specified & AVTAB_XPERMS) + break; + return SEPOL_EEXIST; + } + if (key->source_type < cur->key.source_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type < cur->key.target_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class < cur->key.target_class) + break; + } + + newnode = avtab_insert_node(h, hvalue, prev, key, datum); + if (!newnode) + return SEPOL_ENOMEM; + + return 0; +} + +/* Unlike avtab_insert(), this function allow multiple insertions of the same + * key/specified mask into the table, as needed by the conditional avtab. + * It also returns a pointer to the node inserted. + */ +avtab_ptr_t +ksu_avtab_insert_nonunique(avtab_t * h, avtab_key_t * key, avtab_datum_t * datum) +{ + int hvalue; + avtab_ptr_t prev, cur, newnode; + uint16_t specified = + key->specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD); + + if (!h || !h->htable) + return NULL; + hvalue = avtab_hash(key, h->mask); + for (prev = NULL, cur = h->htable[hvalue]; + cur; prev = cur, cur = cur->next) { + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class == cur->key.target_class && + (specified & cur->key.specified)) + break; + if (key->source_type < cur->key.source_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type < cur->key.target_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class < cur->key.target_class) + break; + } + newnode = avtab_insert_node(h, hvalue, prev, key, datum); + + return newnode; +} + +avtab_datum_t *ksu_avtab_search(avtab_t * h, avtab_key_t * key) +{ + int hvalue; + avtab_ptr_t cur; + uint16_t specified = + key->specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD); + + if (!h || !h->htable) + return NULL; + + hvalue = avtab_hash(key, h->mask); + for (cur = h->htable[hvalue]; cur; cur = cur->next) { + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class == cur->key.target_class && + (specified & cur->key.specified)) + return &cur->datum; + + if (key->source_type < cur->key.source_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type < cur->key.target_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class < cur->key.target_class) + break; + } + + return NULL; +} + +/* This search function returns a node pointer, and can be used in + * conjunction with avtab_search_next_node() + */ +avtab_ptr_t ksu_avtab_search_node(avtab_t * h, avtab_key_t * key) +{ + int hvalue; + avtab_ptr_t cur; + uint16_t specified = + key->specified & ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD); + + if (!h || !h->htable) + return NULL; + + hvalue = avtab_hash(key, h->mask); + for (cur = h->htable[hvalue]; cur; cur = cur->next) { + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class == cur->key.target_class && + (specified & cur->key.specified)) + return cur; + + if (key->source_type < cur->key.source_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type < cur->key.target_type) + break; + if (key->source_type == cur->key.source_type && + key->target_type == cur->key.target_type && + key->target_class < cur->key.target_class) + break; + } + return NULL; +} + +avtab_ptr_t ksu_avtab_search_node_next(avtab_ptr_t node, int specified) +{ + avtab_ptr_t cur; + + if (!node) + return NULL; + + specified &= ~(AVTAB_ENABLED | AVTAB_ENABLED_OLD); + for (cur = node->next; cur; cur = cur->next) { + if (node->key.source_type == cur->key.source_type && + node->key.target_type == cur->key.target_type && + node->key.target_class == cur->key.target_class && + (specified & cur->key.specified)) + return cur; + + if (node->key.source_type < cur->key.source_type) + break; + if (node->key.source_type == cur->key.source_type && + node->key.target_type < cur->key.target_type) + break; + if (node->key.source_type == cur->key.source_type && + node->key.target_type == cur->key.target_type && + node->key.target_class < cur->key.target_class) + break; + } + return NULL; +} + +void ksu_avtab_destroy(avtab_t * h) +{ + unsigned int i; + avtab_ptr_t cur, temp; + + if (!h || !h->htable) + return; + + for (i = 0; i < h->nslot; i++) { + cur = h->htable[i]; + while (cur != NULL) { + if (cur->key.specified & AVTAB_XPERMS) { + free(cur->datum.xperms); + } + temp = cur; + cur = cur->next; + free(temp); + } + h->htable[i] = NULL; + } + free(h->htable); + h->htable = NULL; + h->nslot = 0; + h->mask = 0; +} + +int avtab_map(avtab_t * h, + int (*apply) (avtab_key_t * k, + avtab_datum_t * d, void *args), void *args) +{ + unsigned int i; + int ret; + avtab_ptr_t cur; + + if (!h) + return 0; + + for (i = 0; i < h->nslot; i++) { + cur = h->htable[i]; + while (cur != NULL) { + ret = apply(&cur->key, &cur->datum, args); + if (ret) + return ret; + cur = cur->next; + } + } + return 0; +} + +int ksu_avtab_init(avtab_t * h) +{ + h->htable = NULL; + h->nel = 0; + return 0; +} + +int ksu_avtab_alloc(avtab_t *h, uint32_t nrules) +{ + uint32_t mask = 0; + uint32_t shift = 0; + uint32_t work = nrules; + uint32_t nslot = 0; + + if (nrules == 0) + goto out; + + while (work) { + work = work >> 1; + shift++; + } + if (shift > 2) + shift = shift - 2; + nslot = UINT32_C(1) << shift; + if (nslot > MAX_AVTAB_HASH_BUCKETS) + nslot = MAX_AVTAB_HASH_BUCKETS; + mask = nslot - 1; + + h->htable = calloc(nslot, sizeof(avtab_ptr_t)); + if (!h->htable) + return -1; +out: + h->nel = 0; + h->nslot = nslot; + h->mask = mask; + return 0; +} + +void ksu_avtab_hash_eval(avtab_t * h, char *tag) +{ + unsigned int i, chain_len, slots_used, max_chain_len; + avtab_ptr_t cur; + + slots_used = 0; + max_chain_len = 0; + for (i = 0; i < h->nslot; i++) { + cur = h->htable[i]; + if (cur) { + slots_used++; + chain_len = 0; + while (cur) { + chain_len++; + cur = cur->next; + } + + if (chain_len > max_chain_len) + max_chain_len = chain_len; + } + } + + printf + ("%s: %d entries and %d/%d buckets used, longest chain length %d\n", + tag, h->nel, slots_used, h->nslot, max_chain_len); +} + +/* Ordering of datums in the original avtab format in the policy file. */ +static const uint16_t spec_order[] = { + AVTAB_ALLOWED, + AVTAB_AUDITDENY, + AVTAB_AUDITALLOW, + AVTAB_TRANSITION, + AVTAB_CHANGE, + AVTAB_MEMBER, + AVTAB_XPERMS_ALLOWED, + AVTAB_XPERMS_AUDITALLOW, + AVTAB_XPERMS_DONTAUDIT +}; + +int ksu_avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a, + int (*insertf) (avtab_t * a, avtab_key_t * k, + avtab_datum_t * d, void *p), void *p) +{ + uint8_t buf8; + uint16_t buf16[4], enabled; + uint32_t buf32[8], items, items2, val; + avtab_key_t key; + avtab_datum_t datum; + avtab_extended_perms_t xperms; + unsigned set; + unsigned int i; + int rc; + + memset(&key, 0, sizeof(avtab_key_t)); + memset(&datum, 0, sizeof(avtab_datum_t)); + memset(&xperms, 0, sizeof(avtab_extended_perms_t)); + + if (vers < POLICYDB_VERSION_AVTAB) { + rc = next_entry(buf32, fp, sizeof(uint32_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + return -1; + } + items2 = le32_to_cpu(buf32[0]); + + if (items2 < 5 || items2 > ARRAY_SIZE(buf32)) { + ERR(fp->handle, "invalid item count"); + return -1; + } + + rc = next_entry(buf32, fp, sizeof(uint32_t) * items2); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + return -1; + } + + items = 0; + val = le32_to_cpu(buf32[items++]); + key.source_type = (uint16_t) val; + if (key.source_type != val) { + ERR(fp->handle, "truncated source type"); + return -1; + } + val = le32_to_cpu(buf32[items++]); + key.target_type = (uint16_t) val; + if (key.target_type != val) { + ERR(fp->handle, "truncated target type"); + return -1; + } + val = le32_to_cpu(buf32[items++]); + key.target_class = (uint16_t) val; + if (key.target_class != val) { + ERR(fp->handle, "truncated target class"); + return -1; + } + + val = le32_to_cpu(buf32[items++]); + enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0; + + if (!(val & (AVTAB_AV | AVTAB_TYPE))) { + ERR(fp->handle, "null entry"); + return -1; + } + if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) { + ERR(fp->handle, "entry has both access " + "vectors and types"); + return -1; + } + + for (i = 0; i < ARRAY_SIZE(spec_order); i++) { + if (val & spec_order[i]) { + if (items >= items2) { /* items is index, items2 is total number */ + ERR(fp->handle, "entry has too many items (%d/%d)", + items + 1, items2); + return -1; + } + key.specified = spec_order[i] | enabled; + datum.data = le32_to_cpu(buf32[items++]); + rc = insertf(a, &key, &datum, p); + if (rc) + return rc; + } + } + + if (items != items2) { + ERR(fp->handle, "entry only had %d items, " + "expected %d", items2, items); + return -1; + } + return 0; + } + + rc = next_entry(buf16, fp, sizeof(uint16_t) * 4); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + return -1; + } + items = 0; + key.source_type = le16_to_cpu(buf16[items++]); + key.target_type = le16_to_cpu(buf16[items++]); + key.target_class = le16_to_cpu(buf16[items++]); + key.specified = le16_to_cpu(buf16[items++]); + + set = 0; + for (i = 0; i < ARRAY_SIZE(spec_order); i++) { + if (key.specified & spec_order[i]) + set++; + } + if (!set || set > 1) { + ERR(fp->handle, "more than one specifier"); + return -1; + } + + if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) && + (key.specified & AVTAB_XPERMS)) { + ERR(fp->handle, "policy version %u does not support extended " + "permissions rules and one was specified", vers); + return -1; + } else if (key.specified & AVTAB_XPERMS) { + rc = next_entry(&buf8, fp, sizeof(uint8_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + return -1; + } + xperms.specified = buf8; + rc = next_entry(&buf8, fp, sizeof(uint8_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + return -1; + } + xperms.driver = buf8; + rc = next_entry(buf32, fp, sizeof(uint32_t)*8); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + return -1; + } + for (i = 0; i < ARRAY_SIZE(xperms.perms); i++) + xperms.perms[i] = le32_to_cpu(buf32[i]); + datum.xperms = &xperms; + } else { + rc = next_entry(buf32, fp, sizeof(uint32_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + return -1; + } + datum.data = le32_to_cpu(*buf32); + } + return insertf(a, &key, &datum, p); +} + +static int avtab_insertf(avtab_t * a, avtab_key_t * k, avtab_datum_t * d, + void *p __attribute__ ((unused))) +{ + return avtab_insert(a, k, d); +} + +int ksu_avtab_read(avtab_t * a, struct policy_file *fp, uint32_t vers) +{ + unsigned int i; + int rc; + uint32_t buf[1]; + uint32_t nel; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) { + ERR(fp->handle, "truncated table"); + goto bad; + } + nel = le32_to_cpu(buf[0]); + if (!nel) { + ERR(fp->handle, "table is empty"); + goto bad; + } + + rc = ksu_avtab_alloc(a, nel); + if (rc) { + ERR(fp->handle, "out of memory"); + goto bad; + } + + for (i = 0; i < nel; i++) { + rc = ksu_avtab_read_item(fp, vers, a, avtab_insertf, NULL); + if (rc) { + if (rc == SEPOL_ENOMEM) + ERR(fp->handle, "out of memory"); + if (rc == SEPOL_EEXIST) + ERR(fp->handle, "duplicate entry"); + ERR(fp->handle, "failed on entry %d of %u", i, nel); + goto bad; + } + } + + return 0; + + bad: + ksu_avtab_destroy(a); + return -1; +} diff --git a/kernel/libsepol/src/avtab.o b/kernel/libsepol/src/avtab.o new file mode 100644 index 00000000..59a86776 Binary files /dev/null and b/kernel/libsepol/src/avtab.o differ diff --git a/kernel/libsepol/src/boolean_internal.h b/kernel/libsepol/src/boolean_internal.h new file mode 100644 index 00000000..1c1e6a39 --- /dev/null +++ b/kernel/libsepol/src/boolean_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_BOOLEAN_INTERNAL_H_ +#define _SEPOL_BOOLEAN_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/boolean_record.c b/kernel/libsepol/src/boolean_record.c new file mode 100644 index 00000000..2c7e9a72 --- /dev/null +++ b/kernel/libsepol/src/boolean_record.c @@ -0,0 +1,181 @@ +// #include +// #include +#include + +#include "boolean_internal.h" +#include "debug.h" +#include "kernel.h" + +struct sepol_bool { + /* This boolean's name */ + char *name; + + /* Its value */ + int value; +}; + +struct sepol_bool_key { + /* This boolean's name */ + char *name; +}; + +int sepol_bool_key_create(sepol_handle_t * handle, + const char *name, sepol_bool_key_t ** key_ptr) +{ + + sepol_bool_key_t *tmp_key = + (sepol_bool_key_t *) malloc(sizeof(struct sepol_bool_key)); + + if (!tmp_key) { + ERR(handle, "out of memory, " "could not create boolean key"); + return STATUS_ERR; + } + + tmp_key->name = strdup(name); + if (!tmp_key->name) { + ERR(handle, "out of memory, " "could not create boolean key"); + free(tmp_key); + return STATUS_ERR; + } + + *key_ptr = tmp_key; + return STATUS_SUCCESS; +} + + +void sepol_bool_key_unpack(const sepol_bool_key_t * key, const char **name) +{ + + *name = key->name; +} + + +int sepol_bool_key_extract(sepol_handle_t * handle, + const sepol_bool_t * boolean, + sepol_bool_key_t ** key_ptr) +{ + + if (sepol_bool_key_create(handle, boolean->name, key_ptr) < 0) { + ERR(handle, "could not extract key from boolean %s", + boolean->name); + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_bool_key_free(sepol_bool_key_t * key) +{ + if (!key) + return; + free(key->name); + free(key); +} + +int sepol_bool_compare(const sepol_bool_t * boolean, + const sepol_bool_key_t * key) +{ + + return strcmp(boolean->name, key->name); +} + +int sepol_bool_compare2(const sepol_bool_t * boolean, + const sepol_bool_t * boolean2) +{ + + return strcmp(boolean->name, boolean2->name); +} + +/* Name */ +const char *sepol_bool_get_name(const sepol_bool_t * boolean) +{ + + return boolean->name; +} + + +int sepol_bool_set_name(sepol_handle_t * handle, + sepol_bool_t * boolean, const char *name) +{ + + char *tmp_name = strdup(name); + if (!tmp_name) { + ERR(handle, "out of memory, could not set boolean name"); + return STATUS_ERR; + } + free(boolean->name); + boolean->name = tmp_name; + return STATUS_SUCCESS; +} + + +/* Value */ +int sepol_bool_get_value(const sepol_bool_t * boolean) +{ + + return boolean->value; +} + + +void sepol_bool_set_value(sepol_bool_t * boolean, int value) +{ + + boolean->value = value; +} + + +/* Create */ +int sepol_bool_create(sepol_handle_t * handle, sepol_bool_t ** bool_ptr) +{ + + sepol_bool_t *boolean = (sepol_bool_t *) malloc(sizeof(sepol_bool_t)); + + if (!boolean) { + ERR(handle, "out of memory, " + "could not create boolean record"); + return STATUS_ERR; + } + + boolean->name = NULL; + boolean->value = 0; + + *bool_ptr = boolean; + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_bool_clone(sepol_handle_t * handle, + const sepol_bool_t * boolean, sepol_bool_t ** bool_ptr) +{ + + sepol_bool_t *new_bool = NULL; + + if (sepol_bool_create(handle, &new_bool) < 0) + goto err; + + if (sepol_bool_set_name(handle, new_bool, boolean->name) < 0) + goto err; + + new_bool->value = boolean->value; + + *bool_ptr = new_bool; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not clone boolean record"); + sepol_bool_free(new_bool); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_bool_free(sepol_bool_t * boolean) +{ + + if (!boolean) + return; + + free(boolean->name); + free(boolean); +} + diff --git a/kernel/libsepol/src/boolean_record.o b/kernel/libsepol/src/boolean_record.o new file mode 100644 index 00000000..b4f5bf01 Binary files /dev/null and b/kernel/libsepol/src/boolean_record.o differ diff --git a/kernel/libsepol/src/booleans.c b/kernel/libsepol/src/booleans.c new file mode 100644 index 00000000..9a16355d --- /dev/null +++ b/kernel/libsepol/src/booleans.c @@ -0,0 +1,216 @@ +#include +// #include + +#include "handle.h" +#include "private.h" +#include "debug.h" + +#include +#include +#include +#include +#include "boolean_internal.h" + +static int bool_update(sepol_handle_t * handle, + policydb_t * policydb, + const sepol_bool_key_t * key, const sepol_bool_t * data) +{ + + const char *cname; + char *name; + int value; + cond_bool_datum_t *datum; + + sepol_bool_key_unpack(key, &cname); + name = strdup(cname); + value = sepol_bool_get_value(data); + + if (!name) + goto omem; + + datum = hashtab_search(policydb->p_bools.table, name); + if (!datum) { + ERR(handle, "boolean %s no longer in policy", name); + goto err; + } + if (value != 0 && value != 1) { + ERR(handle, "illegal value %d for boolean %s", value, name); + goto err; + } + + free(name); + datum->state = value; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + free(name); + ERR(handle, "could not update boolean %s", cname); + return STATUS_ERR; +} + +static int bool_to_record(sepol_handle_t * handle, + const policydb_t * policydb, + int bool_idx, sepol_bool_t ** record) +{ + + const char *name = policydb->p_bool_val_to_name[bool_idx]; + cond_bool_datum_t *booldatum = policydb->bool_val_to_struct[bool_idx]; + int value = booldatum->state; + + sepol_bool_t *tmp_record = NULL; + + if (sepol_bool_create(handle, &tmp_record) < 0) + goto err; + + if (sepol_bool_set_name(handle, tmp_record, name) < 0) + goto err; + + sepol_bool_set_value(tmp_record, value); + + *record = tmp_record; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not convert boolean %s to record", name); + sepol_bool_free(tmp_record); + return STATUS_ERR; +} + +int sepol_bool_set(sepol_handle_t * handle, + sepol_policydb_t * p, + const sepol_bool_key_t * key, const sepol_bool_t * data) +{ + + policydb_t *policydb = &p->p; + const char *name; + sepol_bool_key_unpack(key, &name); + + if (bool_update(handle, policydb, key, data) < 0) + goto err; + + if (evaluate_conds(policydb) < 0) { + ERR(handle, "error while re-evaluating conditionals"); + goto err; + } + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not set boolean %s", name); + return STATUS_ERR; +} + +int sepol_bool_count(sepol_handle_t * handle __attribute__ ((unused)), + const sepol_policydb_t * p, unsigned int *response) +{ + + const policydb_t *policydb = &p->p; + *response = policydb->p_bools.nprim; + + return STATUS_SUCCESS; +} + +int sepol_bool_exists(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_bool_key_t * key, int *response) +{ + + const policydb_t *policydb = &p->p; + + const char *cname; + char *name = NULL; + sepol_bool_key_unpack(key, &cname); + name = strdup(cname); + + if (!name) { + ERR(handle, "out of memory, could not check " + "if user %s exists", cname); + return STATUS_ERR; + } + + *response = (hashtab_search(policydb->p_bools.table, name) != NULL); + free(name); + return STATUS_SUCCESS; +} + +int sepol_bool_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_bool_key_t * key, sepol_bool_t ** response) +{ + + const policydb_t *policydb = &p->p; + cond_bool_datum_t *booldatum = NULL; + + const char *cname; + char *name = NULL; + sepol_bool_key_unpack(key, &cname); + name = strdup(cname); + + if (!name) + goto omem; + + booldatum = hashtab_search(policydb->p_bools.table, name); + if (!booldatum) { + *response = NULL; + free(name); + return STATUS_SUCCESS; + } + + if (bool_to_record(handle, policydb, + booldatum->s.value - 1, response) < 0) + goto err; + + free(name); + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + ERR(handle, "could not query boolean %s", cname); + free(name); + return STATUS_ERR; +} + +int sepol_bool_iterate(sepol_handle_t * handle, + const sepol_policydb_t * p, + int (*fn) (const sepol_bool_t * boolean, + void *fn_arg), void *arg) +{ + + const policydb_t *policydb = &p->p; + unsigned int nbools = policydb->p_bools.nprim; + sepol_bool_t *boolean = NULL; + unsigned int i; + + /* For each boolean */ + for (i = 0; i < nbools; i++) { + + int status; + + if (bool_to_record(handle, policydb, i, &boolean) < 0) + goto err; + + /* Invoke handler */ + status = fn(boolean, arg); + if (status < 0) + goto err; + + sepol_bool_free(boolean); + boolean = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not iterate over booleans"); + sepol_bool_free(boolean); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/booleans.o b/kernel/libsepol/src/booleans.o new file mode 100644 index 00000000..f0409190 Binary files /dev/null and b/kernel/libsepol/src/booleans.o differ diff --git a/kernel/libsepol/src/conditional.c b/kernel/libsepol/src/conditional.c new file mode 100644 index 00000000..52b55752 --- /dev/null +++ b/kernel/libsepol/src/conditional.c @@ -0,0 +1,906 @@ +/* Authors: Karl MacMillan + * Frank Mayer + * David Caplan + * + * Copyright (C) 2003 - 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// #include + +#include +#include + +#include "private.h" +#include "debug.h" + +/* move all type rules to top of t/f lists to help kernel on evaluation */ +static void cond_optimize(cond_av_list_t ** l) +{ + cond_av_list_t *top, *p, *cur; + + top = p = cur = *l; + + while (cur) { + if ((cur->node->key.specified & AVTAB_TYPE) && (top != cur)) { + p->next = cur->next; + cur->next = top; + top = cur; + cur = p->next; + } else { + p = cur; + cur = cur->next; + } + } + *l = top; +} + +/* reorder t/f lists for kernel */ +void cond_optimize_lists(cond_list_t * cl) +{ + cond_list_t *n; + + for (n = cl; n != NULL; n = n->next) { + cond_optimize(&n->true_list); + cond_optimize(&n->false_list); + } +} + +static int bool_present(unsigned int target, unsigned int bools[], + unsigned int num_bools) +{ + unsigned int i = 0; + int ret = 1; + + if (num_bools > COND_MAX_BOOLS) { + return 0; + } + while (i < num_bools && target != bools[i]) + i++; + if (i == num_bools) + ret = 0; /* got to end w/o match */ + return ret; +} + +static int same_bools(cond_node_t * a, cond_node_t * b) +{ + unsigned int i, x; + + x = a->nbools; + + /* same number of bools? */ + if (x != b->nbools) + return 0; + + /* make sure all the bools in a are also in b */ + for (i = 0; i < x; i++) + if (!bool_present(a->bool_ids[i], b->bool_ids, x)) + return 0; + return 1; +} + +/* + * Determine if two conditional expressions are equal. + */ +int cond_expr_equal(cond_node_t * a, cond_node_t * b) +{ + cond_expr_t *cur_a, *cur_b; + + if (a == NULL || b == NULL) + return 0; + + if (a->nbools != b->nbools) + return 0; + + /* if exprs have <= COND_MAX_BOOLS we can check the precompute values + * for the expressions. + */ + if (a->nbools <= COND_MAX_BOOLS && b->nbools <= COND_MAX_BOOLS) { + if (!same_bools(a, b)) + return 0; + return (a->expr_pre_comp == b->expr_pre_comp); + } + + /* for long expressions we check for exactly the same expression */ + cur_a = a->expr; + cur_b = b->expr; + while (1) { + if (cur_a == NULL && cur_b == NULL) + return 1; + else if (cur_a == NULL || cur_b == NULL) + return 0; + if (cur_a->expr_type != cur_b->expr_type) + return 0; + if (cur_a->expr_type == COND_BOOL) { + if (cur_a->bool != cur_b->bool) + return 0; + } + cur_a = cur_a->next; + cur_b = cur_b->next; + } + return 1; +} + +/* Create a new conditional node, optionally copying + * the conditional expression from an existing node. + * If node is NULL then a new node will be created + * with no conditional expression. + */ +cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node) +{ + cond_node_t *new_node; + unsigned int i; + + new_node = (cond_node_t *)malloc(sizeof(cond_node_t)); + if (!new_node) { + return NULL; + } + memset(new_node, 0, sizeof(cond_node_t)); + + if (node) { + new_node->expr = cond_copy_expr(node->expr); + if (!new_node->expr) { + free(new_node); + return NULL; + } + new_node->cur_state = cond_evaluate_expr(p, new_node->expr); + new_node->nbools = node->nbools; + for (i = 0; i < min(node->nbools, COND_MAX_BOOLS); i++) + new_node->bool_ids[i] = node->bool_ids[i]; + new_node->expr_pre_comp = node->expr_pre_comp; + new_node->flags = node->flags; + } + + return new_node; +} + +/* Find a conditional (the needle) within a list of existing ones (the + * haystack) that has a matching expression. If found, return a + * pointer to the existing node, setting 'was_created' to 0. + * Otherwise create a new one and return it, setting 'was_created' to + * 1. */ +cond_node_t *cond_node_find(policydb_t * p, + cond_node_t * needle, cond_node_t * haystack, + int *was_created) +{ + while (haystack) { + if (cond_expr_equal(needle, haystack)) { + *was_created = 0; + return haystack; + } + haystack = haystack->next; + } + *was_created = 1; + + return cond_node_create(p, needle); +} + +/* return either a pre-existing matching node or create a new node */ +cond_node_t *cond_node_search(policydb_t * p, cond_node_t * list, + cond_node_t * cn) +{ + int was_created; + cond_node_t *result = cond_node_find(p, cn, list, &was_created); + if (result != NULL && was_created) { + /* add conditional node to policy list */ + result->next = p->cond_list; + p->cond_list = result; + } + return result; +} + +/* + * cond_evaluate_expr evaluates a conditional expr + * in reverse polish notation. It returns true (1), false (0), + * or undefined (-1). Undefined occurs when the expression + * exceeds the stack depth of COND_EXPR_MAXDEPTH. + */ +int cond_evaluate_expr(policydb_t * p, cond_expr_t * expr) +{ + + cond_expr_t *cur; + int s[COND_EXPR_MAXDEPTH]; + int sp = -1; + + s[0] = -1; + + for (cur = expr; cur != NULL; cur = cur->next) { + switch (cur->expr_type) { + case COND_BOOL: + if (sp == (COND_EXPR_MAXDEPTH - 1)) + return -1; + sp++; + s[sp] = p->bool_val_to_struct[cur->bool - 1]->state; + break; + case COND_NOT: + if (sp < 0) + return -1; + s[sp] = !s[sp]; + break; + case COND_OR: + if (sp < 1) + return -1; + sp--; + s[sp] |= s[sp + 1]; + break; + case COND_AND: + if (sp < 1) + return -1; + sp--; + s[sp] &= s[sp + 1]; + break; + case COND_XOR: + if (sp < 1) + return -1; + sp--; + s[sp] ^= s[sp + 1]; + break; + case COND_EQ: + if (sp < 1) + return -1; + sp--; + s[sp] = (s[sp] == s[sp + 1]); + break; + case COND_NEQ: + if (sp < 1) + return -1; + sp--; + s[sp] = (s[sp] != s[sp + 1]); + break; + default: + return -1; + } + } + return s[0]; +} + +cond_expr_t *cond_copy_expr(cond_expr_t * expr) +{ + cond_expr_t *cur, *head, *tail, *new_expr; + tail = head = NULL; + cur = expr; + while (cur) { + new_expr = (cond_expr_t *) malloc(sizeof(cond_expr_t)); + if (!new_expr) + goto free_head; + memset(new_expr, 0, sizeof(cond_expr_t)); + + new_expr->expr_type = cur->expr_type; + new_expr->bool = cur->bool; + + if (!head) + head = new_expr; + if (tail) + tail->next = new_expr; + tail = new_expr; + cur = cur->next; + } + return head; + + free_head: + while (head) { + tail = head->next; + free(head); + head = tail; + } + return NULL; +} + +/* + * evaluate_cond_node evaluates the conditional stored in + * a cond_node_t and if the result is different than the + * current state of the node it sets the rules in the true/false + * list appropriately. If the result of the expression is undefined + * all of the rules are disabled for safety. + */ +static int evaluate_cond_node(policydb_t * p, cond_node_t * node) +{ + int new_state; + cond_av_list_t *cur; + + new_state = cond_evaluate_expr(p, node->expr); + if (new_state != node->cur_state) { + node->cur_state = new_state; + if (new_state == -1) + WARN(NULL, "expression result was undefined - disabling all rules."); + /* turn the rules on or off */ + for (cur = node->true_list; cur != NULL; cur = cur->next) { + if (new_state <= 0) { + cur->node->key.specified &= ~AVTAB_ENABLED; + } else { + cur->node->key.specified |= AVTAB_ENABLED; + } + } + + for (cur = node->false_list; cur != NULL; cur = cur->next) { + /* -1 or 1 */ + if (new_state) { + cur->node->key.specified &= ~AVTAB_ENABLED; + } else { + cur->node->key.specified |= AVTAB_ENABLED; + } + } + } + return 0; +} + +/* precompute and simplify an expression if possible. If left with !expression, change + * to expression and switch t and f. precompute expression for expressions with limited + * number of bools. + */ +int cond_normalize_expr(policydb_t * p, cond_node_t * cn) +{ + cond_expr_t *ne, *e; + cond_av_list_t *tmp; + unsigned int i, j, orig_value[COND_MAX_BOOLS]; + int k; + uint32_t test = 0x0; + avrule_t *tmp2; + + cn->nbools = 0; + + memset(cn->bool_ids, 0, sizeof(cn->bool_ids)); + cn->expr_pre_comp = 0x0; + + /* take care of !expr case */ + ne = NULL; + e = cn->expr; + + /* because it's RPN look at last element */ + while (e->next != NULL) { + ne = e; + e = e->next; + } + if (e->expr_type == COND_NOT) { + if (ne) { + ne->next = NULL; + } else { /* ne should never be NULL */ + ERR(NULL, "Found expr with no bools and only a ! - this should never happen."); + return -1; + } + /* swap the true and false lists */ + tmp = cn->true_list; + cn->true_list = cn->false_list; + cn->false_list = tmp; + tmp2 = cn->avtrue_list; + cn->avtrue_list = cn->avfalse_list; + cn->avfalse_list = tmp2; + + /* free the "not" node in the list */ + free(e); + } + + /* find all the bools in the expression */ + for (e = cn->expr; e != NULL; e = e->next) { + switch (e->expr_type) { + case COND_BOOL: + /* see if we've already seen this bool */ + if (!bool_present(e->bool, cn->bool_ids, cn->nbools)) { + /* count em all but only record up to COND_MAX_BOOLS */ + if (cn->nbools < COND_MAX_BOOLS) + cn->bool_ids[cn->nbools++] = e->bool; + else + cn->nbools++; + } + break; + default: + break; + } + } + + /* only precompute for exprs with <= COND_AX_BOOLS */ + if (cn->nbools <= COND_MAX_BOOLS) { + /* save the default values for the bools so we can play with them */ + for (i = 0; i < cn->nbools; i++) { + orig_value[i] = + p->bool_val_to_struct[cn->bool_ids[i] - 1]->state; + } + + /* loop through all possible combinations of values for bools in expression */ + for (test = 0x0; test < (UINT32_C(1) << cn->nbools); test++) { + /* temporarily set the value for all the bools in the + * expression using the corr. bit in test */ + for (j = 0; j < cn->nbools; j++) { + p->bool_val_to_struct[cn->bool_ids[j] - + 1]->state = + (test & (UINT32_C(1) << j)) ? 1 : 0; + } + k = cond_evaluate_expr(p, cn->expr); + if (k == -1) { + ERR(NULL, "While testing expression, expression result " + "was undefined - this should never happen."); + return -1; + } + /* set the bit if expression evaluates true */ + if (k) + cn->expr_pre_comp |= UINT32_C(1) << test; + } + + /* restore bool default values */ + for (i = 0; i < cn->nbools; i++) + p->bool_val_to_struct[cn->bool_ids[i] - 1]->state = + orig_value[i]; + } + return 0; +} + +int evaluate_conds(policydb_t * p) +{ + int ret; + cond_node_t *cur; + + for (cur = p->cond_list; cur != NULL; cur = cur->next) { + ret = evaluate_cond_node(p, cur); + if (ret) + return ret; + } + return 0; +} + +int ksu_cond_policydb_init(policydb_t * p) +{ + p->bool_val_to_struct = NULL; + p->cond_list = NULL; + if (ksu_avtab_init(&p->te_cond_avtab)) + return -1; + + return 0; +} + +void cond_av_list_destroy(cond_av_list_t * list) +{ + cond_av_list_t *cur, *next; + for (cur = list; cur != NULL; cur = next) { + next = cur->next; + /* the avtab_ptr_t node is destroy by the avtab */ + free(cur); + } +} + +void cond_expr_destroy(cond_expr_t * expr) +{ + cond_expr_t *cur_expr, *next_expr; + + if (!expr) + return; + + for (cur_expr = expr; cur_expr != NULL; cur_expr = next_expr) { + next_expr = cur_expr->next; + free(cur_expr); + } +} + +void cond_node_destroy(cond_node_t * node) +{ + if (!node) + return; + + cond_expr_destroy(node->expr); + avrule_list_destroy(node->avtrue_list); + avrule_list_destroy(node->avfalse_list); + cond_av_list_destroy(node->true_list); + cond_av_list_destroy(node->false_list); +} + +void cond_list_destroy(cond_list_t * list) +{ + cond_node_t *next, *cur; + + if (list == NULL) + return; + + for (cur = list; cur != NULL; cur = next) { + next = cur->next; + cond_node_destroy(cur); + free(cur); + } +} + +void ksu_cond_policydb_destroy(policydb_t * p) +{ + if (p->bool_val_to_struct != NULL) + free(p->bool_val_to_struct); + ksu_avtab_destroy(&p->te_cond_avtab); + cond_list_destroy(p->cond_list); +} + +int ksu_cond_init_bool_indexes(policydb_t * p) +{ + if (p->bool_val_to_struct) + free(p->bool_val_to_struct); + p->bool_val_to_struct = (cond_bool_datum_t **) + calloc(p->p_bools.nprim, sizeof(cond_bool_datum_t *)); + if (!p->bool_val_to_struct) + return -1; + return 0; +} + +int ksu_cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + if (key) + free(key); + free(datum); + return 0; +} + +int ksu_cond_index_bool(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + cond_bool_datum_t *booldatum; + + booldatum = datum; + p = datap; + + if (!booldatum->s.value || booldatum->s.value > p->p_bools.nprim) + return -EINVAL; + + if (p->p_bool_val_to_name[booldatum->s.value - 1] != NULL) + return -EINVAL; + + p->p_bool_val_to_name[booldatum->s.value - 1] = key; + p->bool_val_to_struct[booldatum->s.value - 1] = booldatum; + + return 0; +} + +static int bool_isvalid(cond_bool_datum_t * b) +{ + if (!(b->state == 0 || b->state == 1)) + return 0; + return 1; +} + +int ksu_cond_read_bool(policydb_t * p, + hashtab_t h, + struct policy_file *fp) +{ + char *key = 0; + cond_bool_datum_t *booldatum; + uint32_t buf[3], len; + int rc; + + booldatum = malloc(sizeof(cond_bool_datum_t)); + if (!booldatum) + return -1; + memset(booldatum, 0, sizeof(cond_bool_datum_t)); + + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) + goto err; + + booldatum->s.value = le32_to_cpu(buf[0]); + booldatum->state = le32_to_cpu(buf[1]); + + if (!bool_isvalid(booldatum)) + goto err; + + len = le32_to_cpu(buf[2]); + if (str_read(&key, fp, len)) + goto err; + + if (p->policy_type != POLICY_KERN && + p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto err; + booldatum->flags = le32_to_cpu(buf[0]); + } + + if (hashtab_insert(h, key, booldatum)) + goto err; + + return 0; + err: + ksu_cond_destroy_bool(key, booldatum, 0); + return -1; +} + +struct cond_insertf_data { + struct policydb *p; + cond_av_list_t *other; + cond_av_list_t *head; + cond_av_list_t *tail; +}; + +static int cond_insertf(avtab_t * a + __attribute__ ((unused)), avtab_key_t * k, + avtab_datum_t * d, void *ptr) +{ + struct cond_insertf_data *data = ptr; + struct policydb *p = data->p; + cond_av_list_t *other = data->other, *list, *cur; + avtab_ptr_t node_ptr; + uint8_t found; + + /* + * For type rules we have to make certain there aren't any + * conflicting rules by searching the te_avtab and the + * cond_te_avtab. + */ + if (k->specified & AVTAB_TYPE) { + if (ksu_avtab_search(&p->te_avtab, k)) { + WARN(NULL, "security: type rule already exists outside of a conditional."); + return -1; + } + /* + * If we are reading the false list other will be a pointer to + * the true list. We can have duplicate entries if there is only + * 1 other entry and it is in our true list. + * + * If we are reading the true list (other == NULL) there shouldn't + * be any other entries. + */ + if (other) { + node_ptr = ksu_avtab_search_node(&p->te_cond_avtab, k); + if (node_ptr) { + if (ksu_avtab_search_node_next + (node_ptr, k->specified)) { + ERR(NULL, "security: too many conflicting type rules."); + return -1; + } + found = 0; + for (cur = other; cur != NULL; cur = cur->next) { + if (cur->node == node_ptr) { + found = 1; + break; + } + } + if (!found) { + ERR(NULL, "security: conflicting type rules."); + return -1; + } + } + } else { + if (ksu_avtab_search(&p->te_cond_avtab, k)) { + ERR(NULL, "security: conflicting type rules when adding type rule for true."); + return -1; + } + } + } + + node_ptr = ksu_avtab_insert_nonunique(&p->te_cond_avtab, k, d); + if (!node_ptr) { + ERR(NULL, "security: could not insert rule."); + return -1; + } + node_ptr->parse_context = (void *)1; + + list = malloc(sizeof(cond_av_list_t)); + if (!list) + return -1; + memset(list, 0, sizeof(cond_av_list_t)); + + list->node = node_ptr; + if (!data->head) + data->head = list; + else + data->tail->next = list; + data->tail = list; + return 0; +} + +static int cond_read_av_list(policydb_t * p, void *fp, + cond_av_list_t ** ret_list, cond_av_list_t * other) +{ + unsigned int i; + int rc; + uint32_t buf[1], len; + struct cond_insertf_data data; + + *ret_list = NULL; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + + len = le32_to_cpu(buf[0]); + if (len == 0) { + return 0; + } + + data.p = p; + data.other = other; + data.head = NULL; + data.tail = NULL; + for (i = 0; i < len; i++) { + rc = ksu_avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, + cond_insertf, &data); + if (rc) { + cond_av_list_destroy(data.head); + return rc; + } + + } + + *ret_list = data.head; + return 0; +} + +static int expr_isvalid(policydb_t * p, cond_expr_t * expr) +{ + if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { + WARN(NULL, "security: conditional expressions uses unknown operator."); + return 0; + } + + if (expr->bool > p->p_bools.nprim) { + WARN(NULL, "security: conditional expressions uses unknown bool."); + return 0; + } + return 1; +} + +static int cond_read_node(policydb_t * p, cond_node_t * node, void *fp) +{ + uint32_t buf[2]; + int len, i, rc; + cond_expr_t *expr = NULL, *last = NULL; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto err; + + node->cur_state = le32_to_cpu(buf[0]); + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto err; + + /* expr */ + len = le32_to_cpu(buf[0]); + + for (i = 0; i < len; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + goto err; + + expr = malloc(sizeof(cond_expr_t)); + if (!expr) { + goto err; + } + memset(expr, 0, sizeof(cond_expr_t)); + + expr->expr_type = le32_to_cpu(buf[0]); + expr->bool = le32_to_cpu(buf[1]); + + if (!expr_isvalid(p, expr)) { + free(expr); + goto err; + } + + if (i == 0) { + node->expr = expr; + } else { + last->next = expr; + } + last = expr; + } + + if (p->policy_type == POLICY_KERN) { + if (cond_read_av_list(p, fp, &node->true_list, NULL) != 0) + goto err; + if (cond_read_av_list(p, fp, &node->false_list, node->true_list) + != 0) + goto err; + } else { + if (avrule_read_list(p, &node->avtrue_list, fp)) + goto err; + if (avrule_read_list(p, &node->avfalse_list, fp)) + goto err; + } + + if (p->policy_type != POLICY_KERN && + p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto err; + node->flags = le32_to_cpu(buf[0]); + } + + return 0; + err: + cond_node_destroy(node); + free(node); + return -1; +} + +int ksu_cond_read_list(policydb_t * p, cond_list_t ** list, void *fp) +{ + cond_node_t *node, *last = NULL; + uint32_t buf[1]; + int i, len, rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + + len = le32_to_cpu(buf[0]); + + rc = ksu_avtab_alloc(&p->te_cond_avtab, p->te_avtab.nel); + if (rc) + goto err; + + for (i = 0; i < len; i++) { + node = malloc(sizeof(cond_node_t)); + if (!node) + goto err; + memset(node, 0, sizeof(cond_node_t)); + + if (cond_read_node(p, node, fp) != 0) + goto err; + + if (i == 0) { + *list = node; + } else { + last->next = node; + } + last = node; + } + return 0; + err: + return -1; +} + +/* Determine whether additional permissions are granted by the conditional + * av table, and if so, add them to the result + */ +void ksu_cond_compute_av(avtab_t * ctab, avtab_key_t * key, + struct sepol_av_decision *avd) +{ + avtab_ptr_t node; + + if (!ctab || !key || !avd) + return; + + for (node = ksu_avtab_search_node(ctab, key); node != NULL; + node = ksu_avtab_search_node_next(node, key->specified)) { + if ((uint16_t) (AVTAB_ALLOWED | AVTAB_ENABLED) == + (node->key.specified & (AVTAB_ALLOWED | AVTAB_ENABLED))) + avd->allowed |= node->datum.data; + if ((uint16_t) (AVTAB_AUDITDENY | AVTAB_ENABLED) == + (node->key.specified & (AVTAB_AUDITDENY | AVTAB_ENABLED))) + /* Since a '0' in an auditdeny mask represents a + * permission we do NOT want to audit (dontaudit), we use + * the '&' operand to ensure that all '0's in the mask + * are retained (much unlike the allow and auditallow cases). + */ + avd->auditdeny &= node->datum.data; + if ((uint16_t) (AVTAB_AUDITALLOW | AVTAB_ENABLED) == + (node->key.specified & (AVTAB_AUDITALLOW | AVTAB_ENABLED))) + avd->auditallow |= node->datum.data; + } + return; +} + +avtab_datum_t *cond_av_list_search(avtab_key_t * key, + cond_av_list_t * cond_list) +{ + + cond_av_list_t *cur_av; + + for (cur_av = cond_list; cur_av != NULL; cur_av = cur_av->next) { + + if (cur_av->node->key.source_type == key->source_type && + cur_av->node->key.target_type == key->target_type && + cur_av->node->key.target_class == key->target_class) + + return &cur_av->node->datum; + + } + return NULL; + +} diff --git a/kernel/libsepol/src/conditional.o b/kernel/libsepol/src/conditional.o new file mode 100644 index 00000000..60c67a78 Binary files /dev/null and b/kernel/libsepol/src/conditional.o differ diff --git a/kernel/libsepol/src/constraint.c b/kernel/libsepol/src/constraint.c new file mode 100644 index 00000000..78a2413c --- /dev/null +++ b/kernel/libsepol/src/constraint.c @@ -0,0 +1,52 @@ +/* Authors: Jason Tang + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +// #include +// #include +#include "kernel.h" + +int constraint_expr_init(constraint_expr_t * expr) +{ + memset(expr, 0, sizeof(*expr)); + ebitmap_init(&expr->names); + if ((expr->type_names = malloc(sizeof(*expr->type_names))) == NULL) { + return -1; + } + type_set_init(expr->type_names); + return 0; +} + +void constraint_expr_destroy(constraint_expr_t * expr) +{ + constraint_expr_t *next; + + while (expr != NULL) { + next = expr->next; + ksu_ebitmap_destroy(&expr->names); + type_set_destroy(expr->type_names); + free(expr->type_names); + free(expr); + expr = next; + } +} diff --git a/kernel/libsepol/src/constraint.o b/kernel/libsepol/src/constraint.o new file mode 100644 index 00000000..2e52d5bf Binary files /dev/null and b/kernel/libsepol/src/constraint.o differ diff --git a/kernel/libsepol/src/context.c b/kernel/libsepol/src/context.c new file mode 100644 index 00000000..9fc8bb0a --- /dev/null +++ b/kernel/libsepol/src/context.c @@ -0,0 +1,343 @@ +// #include +#include +// #include + +#include +#include +#include "context_internal.h" + +#include "debug.h" +#include "context.h" +#include "handle.h" +#include "mls.h" +#include "private.h" + +/* ----- Compatibility ---- */ +int ksu_policydb_context_isvalid(const policydb_t * p, const context_struct_t * c) +{ + + return context_is_valid(p, c); +} + +int sepol_check_context(const char *context) +{ + + return sepol_context_to_sid(context, + strlen(context) + 1, NULL); +} + +/* ---- End compatibility --- */ + +/* + * Return 1 if the fields in the security context + * structure `c' are valid. Return 0 otherwise. + */ +int context_is_valid(const policydb_t * p, const context_struct_t * c) +{ + + role_datum_t *role; + user_datum_t *usrdatum; + ebitmap_t types, roles; + + ebitmap_init(&types); + ebitmap_init(&roles); + if (!c->role || c->role > p->p_roles.nprim) + return 0; + + if (!c->user || c->user > p->p_users.nprim) + return 0; + + if (!c->type || c->type > p->p_types.nprim) + return 0; + + if (c->role != OBJECT_R_VAL) { + /* + * Role must be authorized for the type. + */ + role = p->role_val_to_struct[c->role - 1]; + if (!role || !ksu_ebitmap_get_bit(&role->cache, c->type - 1)) + /* role may not be associated with type */ + return 0; + + /* + * User must be authorized for the role. + */ + usrdatum = p->user_val_to_struct[c->user - 1]; + if (!usrdatum) + return 0; + + if (!ksu_ebitmap_get_bit(&usrdatum->cache, c->role - 1)) + /* user may not be associated with role */ + return 0; + } + + if (!ksu_mls_context_isvalid(p, c)) + return 0; + + return 1; +} + +/* + * Write the security context string representation of + * the context structure `context' into a dynamically + * allocated string of the correct size. Set `*scontext' + * to point to this string and set `*scontext_len' to + * the length of the string. + */ +int context_to_string(sepol_handle_t * handle, + const policydb_t * policydb, + const context_struct_t * context, + char **result, size_t * result_len) +{ + + char *scontext = NULL; + size_t scontext_len = 0; + char *ptr; + + /* Compute the size of the context. */ + scontext_len += + strlen(policydb->p_user_val_to_name[context->user - 1]) + 1; + scontext_len += + strlen(policydb->p_role_val_to_name[context->role - 1]) + 1; + scontext_len += strlen(policydb->p_type_val_to_name[context->type - 1]); + scontext_len += ksu_mls_compute_context_len(policydb, context); + + /* We must null terminate the string */ + scontext_len += 1; + + /* Allocate space for the context; caller must free this space. */ + scontext = malloc(scontext_len); + if (!scontext) + goto omem; + scontext[scontext_len - 1] = '\0'; + + /* + * Copy the user name, role name and type name into the context. + */ + ptr = scontext; + sprintf(ptr, "%s:%s:%s", + policydb->p_user_val_to_name[context->user - 1], + policydb->p_role_val_to_name[context->role - 1], + policydb->p_type_val_to_name[context->type - 1]); + + ptr += + strlen(policydb->p_user_val_to_name[context->user - 1]) + 1 + + strlen(policydb->p_role_val_to_name[context->role - 1]) + 1 + + strlen(policydb->p_type_val_to_name[context->type - 1]); + + ksu_mls_sid_to_context(policydb, context, &ptr); + + *result = scontext; + *result_len = scontext_len; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory, could not convert " "context to string"); + free(scontext); + return STATUS_ERR; +} + +/* + * Create a context structure from the given record + */ +int context_from_record(sepol_handle_t * handle, + const policydb_t * policydb, + context_struct_t ** cptr, + const sepol_context_t * record) +{ + + context_struct_t *scontext = NULL; + user_datum_t *usrdatum; + role_datum_t *roldatum; + type_datum_t *typdatum; + + /* Hashtab keys are not constant - suppress warnings */ + char *user = strdup(sepol_context_get_user(record)); + char *role = strdup(sepol_context_get_role(record)); + char *type = strdup(sepol_context_get_type(record)); + const char *mls = sepol_context_get_mls(record); + + scontext = (context_struct_t *) malloc(sizeof(context_struct_t)); + if (!user || !role || !type || !scontext) { + ERR(handle, "out of memory"); + goto err; + } + context_init(scontext); + + /* User */ + usrdatum = (user_datum_t *) hashtab_search(policydb->p_users.table, + (hashtab_key_t) user); + if (!usrdatum) { + ERR(handle, "user %s is not defined", user); + goto err_destroy; + } + scontext->user = usrdatum->s.value; + + /* Role */ + roldatum = (role_datum_t *) hashtab_search(policydb->p_roles.table, + (hashtab_key_t) role); + if (!roldatum) { + ERR(handle, "role %s is not defined", role); + goto err_destroy; + } + scontext->role = roldatum->s.value; + + /* Type */ + typdatum = (type_datum_t *) hashtab_search(policydb->p_types.table, + (hashtab_key_t) type); + if (!typdatum || typdatum->flavor == TYPE_ATTRIB) { + ERR(handle, "type %s is not defined", type); + goto err_destroy; + } + scontext->type = typdatum->s.value; + + /* MLS */ + if (mls && !policydb->mls) { + ERR(handle, "MLS is disabled, but MLS context \"%s\" found", + mls); + goto err_destroy; + } else if (!mls && policydb->mls) { + ERR(handle, "MLS is enabled, but no MLS context found"); + goto err_destroy; + } + if (mls && (ksu_mls_from_string(handle, policydb, mls, scontext) < 0)) + goto err_destroy; + + /* Validity check */ + if (!context_is_valid(policydb, scontext)) { + if (mls) { + ERR(handle, + "invalid security context: \"%s:%s:%s:%s\"", + user, role, type, mls); + } else { + ERR(handle, + "invalid security context: \"%s:%s:%s\"", + user, role, type); + } + goto err_destroy; + } + + *cptr = scontext; + free(user); + free(type); + free(role); + return STATUS_SUCCESS; + + err_destroy: + // errno = EINVAL; + context_destroy(scontext); + + err: + free(scontext); + free(user); + free(type); + free(role); + ERR(handle, "could not create context structure"); + return STATUS_ERR; +} + +/* + * Create a record from the given context structure + */ +int context_to_record(sepol_handle_t * handle, + const policydb_t * policydb, + const context_struct_t * context, + sepol_context_t ** record) +{ + + sepol_context_t *tmp_record = NULL; + char *mls = NULL; + + if (sepol_context_create(handle, &tmp_record) < 0) + goto err; + + if (sepol_context_set_user(handle, tmp_record, + policydb->p_user_val_to_name[context->user - + 1]) < 0) + goto err; + + if (sepol_context_set_role(handle, tmp_record, + policydb->p_role_val_to_name[context->role - + 1]) < 0) + goto err; + + if (sepol_context_set_type(handle, tmp_record, + policydb->p_type_val_to_name[context->type - + 1]) < 0) + goto err; + + if (policydb->mls) { + if (mls_to_string(handle, policydb, context, &mls) < 0) + goto err; + + if (sepol_context_set_mls(handle, tmp_record, mls) < 0) + goto err; + } + + free(mls); + *record = tmp_record; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not create context record"); + sepol_context_free(tmp_record); + free(mls); + return STATUS_ERR; +} + +/* + * Create a context structure from the provided string. + */ +int context_from_string(sepol_handle_t * handle, + const policydb_t * policydb, + context_struct_t ** cptr, + const char *con_str, size_t con_str_len) +{ + + char *con_cpy = NULL; + sepol_context_t *ctx_record = NULL; + + if (zero_or_saturated(con_str_len)) { + ERR(handle, "Invalid context length"); + goto err; + } + + /* sepol_context_from_string expects a NULL-terminated string */ + con_cpy = malloc(con_str_len + 1); + if (!con_cpy) { + ERR(handle, "out of memory"); + goto err; + } + + memcpy(con_cpy, con_str, con_str_len); + con_cpy[con_str_len] = '\0'; + + if (sepol_context_from_string(handle, con_cpy, &ctx_record) < 0) + goto err; + + /* Now create from the data structure */ + if (context_from_record(handle, policydb, cptr, ctx_record) < 0) + goto err; + + free(con_cpy); + sepol_context_free(ctx_record); + return STATUS_SUCCESS; + + err: + ERR(handle, "could not create context structure"); + free(con_cpy); + sepol_context_free(ctx_record); + return STATUS_ERR; +} + +int sepol_context_check(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const sepol_context_t * context) +{ + + context_struct_t *con = NULL; + int ret = context_from_record(handle, &policydb->p, &con, context); + context_destroy(con); + free(con); + return ret; +} diff --git a/kernel/libsepol/src/context.h b/kernel/libsepol/src/context.h new file mode 100644 index 00000000..d25ca8a0 --- /dev/null +++ b/kernel/libsepol/src/context.h @@ -0,0 +1,37 @@ +#ifndef _SEPOL_INTERNAL_CONTEXT_H_ +#define _SEPOL_INTERNAL_CONTEXT_H_ + +#include +#include "context_internal.h" +#include +#include +#include + +/* Create a context structure from high level representation */ +extern int context_from_record(sepol_handle_t * handle, + const policydb_t * policydb, + context_struct_t ** cptr, + const sepol_context_t * data); + +extern int context_to_record(sepol_handle_t * handle, + const policydb_t * policydb, + const context_struct_t * context, + sepol_context_t ** record); + +/* Create a context structure from string representation */ +extern int context_from_string(sepol_handle_t * handle, + const policydb_t * policydb, + context_struct_t ** cptr, + const char *con_str, size_t con_str_len); + +/* Check if the provided context is valid for this policy */ +extern int context_is_valid(const policydb_t * policydb, + const context_struct_t * context); + +/* Extract the context as string */ +extern int context_to_string(sepol_handle_t * handle, + const policydb_t * policydb, + const context_struct_t * context, + char **result, size_t * result_len); + +#endif diff --git a/kernel/libsepol/src/context.o b/kernel/libsepol/src/context.o new file mode 100644 index 00000000..83f8dd14 Binary files /dev/null and b/kernel/libsepol/src/context.o differ diff --git a/kernel/libsepol/src/context_internal.h b/kernel/libsepol/src/context_internal.h new file mode 100644 index 00000000..3dc9cd15 --- /dev/null +++ b/kernel/libsepol/src/context_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_CONTEXT_INTERNAL_H_ +#define _SEPOL_CONTEXT_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/context_record.c b/kernel/libsepol/src/context_record.c new file mode 100644 index 00000000..709ef42f --- /dev/null +++ b/kernel/libsepol/src/context_record.c @@ -0,0 +1,321 @@ +// #include +// #include +#include +// #include + +#include "context_internal.h" +#include "debug.h" +#include "private.h" + +struct sepol_context { + + /* Selinux user */ + char *user; + + /* Selinux role */ + char *role; + + /* Selinux type */ + char *type; + + /* MLS */ + char *mls; +}; + +/* User */ +const char *sepol_context_get_user(const sepol_context_t * con) +{ + + return con->user; +} + + +int sepol_context_set_user(sepol_handle_t * handle, + sepol_context_t * con, const char *user) +{ + + char *tmp_user = strdup(user); + if (!tmp_user) { + ERR(handle, "out of memory, could not set " + "context user to %s", user); + return STATUS_ERR; + } + + free(con->user); + con->user = tmp_user; + return STATUS_SUCCESS; +} + + +/* Role */ +const char *sepol_context_get_role(const sepol_context_t * con) +{ + + return con->role; +} + + +int sepol_context_set_role(sepol_handle_t * handle, + sepol_context_t * con, const char *role) +{ + + char *tmp_role = strdup(role); + if (!tmp_role) { + ERR(handle, "out of memory, could not set " + "context role to %s", role); + return STATUS_ERR; + } + free(con->role); + con->role = tmp_role; + return STATUS_SUCCESS; +} + + +/* Type */ +const char *sepol_context_get_type(const sepol_context_t * con) +{ + + return con->type; +} + + +int sepol_context_set_type(sepol_handle_t * handle, + sepol_context_t * con, const char *type) +{ + + char *tmp_type = strdup(type); + if (!tmp_type) { + ERR(handle, "out of memory, could not set " + "context type to %s", type); + return STATUS_ERR; + } + free(con->type); + con->type = tmp_type; + return STATUS_SUCCESS; +} + + +/* MLS */ +const char *sepol_context_get_mls(const sepol_context_t * con) +{ + + return con->mls; +} + + +int sepol_context_set_mls(sepol_handle_t * handle, + sepol_context_t * con, const char *mls) +{ + + char *tmp_mls = strdup(mls); + if (!tmp_mls) { + ERR(handle, "out of memory, could not set " + "MLS fields to %s", mls); + return STATUS_ERR; + } + free(con->mls); + con->mls = tmp_mls; + return STATUS_SUCCESS; +} + + +/* Create */ +int sepol_context_create(sepol_handle_t * handle, sepol_context_t ** con_ptr) +{ + + sepol_context_t *con = + (sepol_context_t *) malloc(sizeof(sepol_context_t)); + + if (!con) { + ERR(handle, "out of memory, could not create context"); + return STATUS_ERR; + } + + con->user = NULL; + con->role = NULL; + con->type = NULL; + con->mls = NULL; + *con_ptr = con; + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_context_clone(sepol_handle_t * handle, + const sepol_context_t * con, sepol_context_t ** con_ptr) +{ + + sepol_context_t *new_con = NULL; + + if (!con) { + *con_ptr = NULL; + return 0; + } + + if (sepol_context_create(handle, &new_con) < 0) + goto err; + + if (!(new_con->user = strdup(con->user))) + goto omem; + + if (!(new_con->role = strdup(con->role))) + goto omem; + + if (!(new_con->type = strdup(con->type))) + goto omem; + + if (con->mls && !(new_con->mls = strdup(con->mls))) + goto omem; + + *con_ptr = new_con; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + ERR(handle, "could not clone context record"); + sepol_context_free(new_con); + return STATUS_ERR; +} + + +/* Destroy */ +void sepol_context_free(sepol_context_t * con) +{ + + if (!con) + return; + + free(con->user); + free(con->role); + free(con->type); + free(con->mls); + free(con); +} + + +int sepol_context_from_string(sepol_handle_t * handle, + const char *str, sepol_context_t ** con) +{ + + char *tmp = NULL, *low, *high; + sepol_context_t *tmp_con = NULL; + + if (!strcmp(str, "<>")) { + *con = NULL; + return STATUS_SUCCESS; + } + + if (sepol_context_create(handle, &tmp_con) < 0) + goto err; + + /* Working copy context */ + tmp = strdup(str); + if (!tmp) { + ERR(handle, "out of memory"); + goto err; + } + low = tmp; + + /* Then, break it into its components */ + + /* User */ + if (!(high = strchr(low, ':'))) + goto mcontext; + else + *high++ = '\0'; + if (sepol_context_set_user(handle, tmp_con, low) < 0) + goto err; + low = high; + + /* Role */ + if (!(high = strchr(low, ':'))) + goto mcontext; + else + *high++ = '\0'; + if (sepol_context_set_role(handle, tmp_con, low) < 0) + goto err; + low = high; + + /* Type, and possibly MLS */ + if (!(high = strchr(low, ':'))) { + if (sepol_context_set_type(handle, tmp_con, low) < 0) + goto err; + } else { + *high++ = '\0'; + if (sepol_context_set_type(handle, tmp_con, low) < 0) + goto err; + low = high; + if (sepol_context_set_mls(handle, tmp_con, low) < 0) + goto err; + } + + free(tmp); + *con = tmp_con; + + return STATUS_SUCCESS; + + mcontext: + // errno = EINVAL; + ERR(handle, "malformed context \"%s\"", str); + + err: + ERR(handle, "could not construct context from string"); + free(tmp); + sepol_context_free(tmp_con); + return STATUS_ERR; +} + +int sepol_context_to_string(sepol_handle_t * handle, + const sepol_context_t * con, char **str_ptr) +{ + + int rc; + char *str = NULL; + size_t total_sz = 0, i; + const size_t sizes[] = { + strlen(con->user), /* user length */ + strlen(con->role), /* role length */ + strlen(con->type), /* type length */ + (con->mls) ? strlen(con->mls) : 0, /* mls length */ + ((con->mls) ? 3 : 2) + 1 /* mls has extra ":" also null byte */ + }; + + for (i = 0; i < ARRAY_SIZE(sizes); i++) { + if (__builtin_add_overflow(total_sz, sizes[i], &total_sz)) { + ERR(handle, "invalid size, overflow at position: %zu", i); + goto err; + } + } + + str = (char *)malloc(total_sz); + if (!str) { + ERR(handle, "out of memory"); + goto err; + } + if (con->mls) { + rc = snprintf(str, total_sz, "%s:%s:%s:%s", + con->user, con->role, con->type, con->mls); + } else { + rc = snprintf(str, total_sz, "%s:%s:%s", + con->user, con->role, con->type); + } + + /* + * rc is >= 0 on the size_t cast and is safe to promote + * to an unsigned value. + */ + if (rc < 0 || (size_t)rc >= total_sz) { + ERR(handle, "print error"); + goto err; + } + + *str_ptr = str; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not convert context to string"); + free(str); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/context_record.o b/kernel/libsepol/src/context_record.o new file mode 100644 index 00000000..209bb91a Binary files /dev/null and b/kernel/libsepol/src/context_record.o differ diff --git a/kernel/libsepol/src/debug.c b/kernel/libsepol/src/debug.c new file mode 100644 index 00000000..41172a4d --- /dev/null +++ b/kernel/libsepol/src/debug.c @@ -0,0 +1,85 @@ +// #include +// #include +// #include +#include "handle.h" +#include "debug.h" + +/* Deprecated */ +struct sepol_handle sepol_compat_handle = { + .msg_callback = sepol_msg_default_handler, + .msg_callback_arg = NULL, +}; + +void sepol_debug(int on) +{ + sepol_compat_handle.msg_callback = (on) ? + sepol_msg_default_handler : NULL; +} + +/* End deprecated */ + +int sepol_msg_get_level(sepol_handle_t * handle) +{ + return handle->msg_level; +} + + +const char *sepol_msg_get_channel(sepol_handle_t * handle) +{ + return handle->msg_channel; +} + + +const char *sepol_msg_get_fname(sepol_handle_t * handle) +{ + return handle->msg_fname; +} + +#ifdef __GNUC__ + __attribute__ ((format(printf, 3, 4))) +#endif +void sepol_msg_default_handler(void *varg __attribute__ ((unused)), + sepol_handle_t * handle, + const char *fmt, ...) +{ +#if 0 + FILE *stream = NULL; + va_list ap; + + switch (sepol_msg_get_level(handle)) { + + case SEPOL_MSG_ERR: + case SEPOL_MSG_WARN: + stream = stderr; + break; + case SEPOL_MSG_INFO: + default: + stream = stdout; + break; + } + + fprintf(stream, "%s.%s: ", + sepol_msg_get_channel(handle), sepol_msg_get_fname(handle)); + + va_start(ap, fmt); + vfprintf(stream, fmt, ap); + va_end(ap); + + fprintf(stream, "\n"); +#endif +} + +extern void sepol_msg_set_callback(sepol_handle_t * handle, +#ifdef __GNUC__ + __attribute__ ((format(printf, 3, 4))) +#endif + void (*msg_callback) (void *varg, + sepol_handle_t * + handle, + const char *fmt, ...), + void *msg_callback_arg) +{ + + handle->msg_callback = msg_callback; + handle->msg_callback_arg = msg_callback_arg; +} diff --git a/kernel/libsepol/src/debug.h b/kernel/libsepol/src/debug.h new file mode 100644 index 00000000..5d5716dd --- /dev/null +++ b/kernel/libsepol/src/debug.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_INTERNAL_DEBUG_H_ +#define _SEPOL_INTERNAL_DEBUG_H_ + +// #include +#include +#include "handle.h" +#include "kernel.h" + +#define STATUS_SUCCESS 0 +#define STATUS_ERR -1 +#define STATUS_NODATA 1 + +/* FIXME: this needs to become a real function. Declaring variables + * in a macro is _evil_ as it can shadow other variables in local scope. + * The variable h has been renamed to _sepol_h to reduce this chance, but + * it is still wrong. + */ +#define msg_write(handle_arg, level_arg, \ + channel_arg, func_arg, ...) do { \ + sepol_handle_t *_sepol_h = (handle_arg) ?: &sepol_compat_handle; \ + if (_sepol_h->msg_callback) { \ + _sepol_h->msg_fname = func_arg; \ + _sepol_h->msg_channel = channel_arg; \ + _sepol_h->msg_level = level_arg; \ + \ + _sepol_h->msg_callback( \ + _sepol_h->msg_callback_arg, \ + _sepol_h, __VA_ARGS__); \ + } \ + } while(0) + +#define ERR(handle, ...) \ + msg_write(handle, SEPOL_MSG_ERR, "libsepol", \ + __FUNCTION__, __VA_ARGS__) + +#define INFO(handle, ...) \ + msg_write(handle, SEPOL_MSG_INFO, "libsepol", \ + __FUNCTION__, __VA_ARGS__) + +#ifdef WARN +#undef WARN +#endif +#define WARN(handle, ...) \ + msg_write(handle, SEPOL_MSG_WARN, "libsepol", \ + __FUNCTION__, __VA_ARGS__) + +// #ifdef __GNUC__ +// __attribute__ ((format(printf, 3, 4))) +// #endif +extern void sepol_msg_default_handler(void *varg, + sepol_handle_t * msg, + const char *fmt, ...); + +extern struct sepol_handle sepol_compat_handle; + +#endif diff --git a/kernel/libsepol/src/debug.o b/kernel/libsepol/src/debug.o new file mode 100644 index 00000000..1b72889a Binary files /dev/null and b/kernel/libsepol/src/debug.o differ diff --git a/kernel/libsepol/src/ebitmap.c b/kernel/libsepol/src/ebitmap.c new file mode 100644 index 00000000..d783eb2d --- /dev/null +++ b/kernel/libsepol/src/ebitmap.c @@ -0,0 +1,496 @@ + +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * Implementation of the extensible bitmap type. + */ + +// #include + +#include +#include + +#include "debug.h" +#include "private.h" + +int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2) +{ + const ebitmap_node_t *n1, *n2; + ebitmap_node_t *new, *prev; + + ebitmap_init(dst); + + n1 = e1->node; + n2 = e2->node; + prev = 0; + while (n1 || n2) { + new = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); + if (!new) { + ksu_ebitmap_destroy(dst); + return -ENOMEM; + } + memset(new, 0, sizeof(ebitmap_node_t)); + if (n1 && n2 && n1->startbit == n2->startbit) { + new->startbit = n1->startbit; + new->map = n1->map | n2->map; + n1 = n1->next; + n2 = n2->next; + } else if (!n2 || (n1 && n1->startbit < n2->startbit)) { + new->startbit = n1->startbit; + new->map = n1->map; + n1 = n1->next; + } else { + new->startbit = n2->startbit; + new->map = n2->map; + n2 = n2->next; + } + + new->next = 0; + if (prev) + prev->next = new; + else + dst->node = new; + prev = new; + } + + dst->highbit = (e1->highbit > e2->highbit) ? e1->highbit : e2->highbit; + return 0; +} + +int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1) +{ + ebitmap_t tmp; + + if (ebitmap_or(&tmp, dst, e1)) + return -1; + ksu_ebitmap_destroy(dst); + dst->node = tmp.node; + dst->highbit = tmp.highbit; + + return 0; +} + +int ksu_ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2) +{ + unsigned int i, length = min(ebitmap_length(e1), ebitmap_length(e2)); + ebitmap_init(dst); + for (i=0; i < length; i++) { + if (ksu_ebitmap_get_bit(e1, i) && ksu_ebitmap_get_bit(e2, i)) { + int rc = ksu_ebitmap_set_bit(dst, i, 1); + if (rc < 0) + return rc; + } + } + return 0; +} + +int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2) +{ + unsigned int i, length = max(ebitmap_length(e1), ebitmap_length(e2)); + ebitmap_init(dst); + for (i=0; i < length; i++) { + int val = ksu_ebitmap_get_bit(e1, i) ^ ksu_ebitmap_get_bit(e2, i); + int rc = ksu_ebitmap_set_bit(dst, i, val); + if (rc < 0) + return rc; + } + return 0; +} + +int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit) +{ + unsigned int i; + ebitmap_init(dst); + for (i=0; i < maxbit; i++) { + int val = ksu_ebitmap_get_bit(e1, i); + int rc = ksu_ebitmap_set_bit(dst, i, !val); + if (rc < 0) + return rc; + } + return 0; +} + +int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit) +{ + int rc; + ebitmap_t e3; + ebitmap_init(dst); + rc = ebitmap_not(&e3, e2, maxbit); + if (rc < 0) + return rc; + rc = ksu_ebitmap_and(dst, e1, &e3); + ksu_ebitmap_destroy(&e3); + if (rc < 0) + return rc; + return 0; +} + +unsigned int ebitmap_cardinality(const ebitmap_t *e1) +{ + unsigned int count = 0; + const ebitmap_node_t *n; + + for (n = e1->node; n; n = n->next) { + count += __builtin_popcountll(n->map); + } + return count; +} + +int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2) +{ + int rc; + ebitmap_t tmp; + int distance; + if (ksu_ebitmap_cmp(e1, e2)) + return 0; + rc = ebitmap_xor(&tmp, e1, e2); + if (rc < 0) + return -1; + distance = ebitmap_cardinality(&tmp); + ksu_ebitmap_destroy(&tmp); + return distance; +} + +int ksu_ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2) +{ + const ebitmap_node_t *n1, *n2; + + if (e1->highbit != e2->highbit) + return 0; + + n1 = e1->node; + n2 = e2->node; + while (n1 && n2 && + (n1->startbit == n2->startbit) && (n1->map == n2->map)) { + n1 = n1->next; + n2 = n2->next; + } + + if (n1 || n2) + return 0; + + return 1; +} + +int ksu_ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src) +{ + const ebitmap_node_t *n; + ebitmap_node_t *new, *prev; + + ebitmap_init(dst); + n = src->node; + prev = 0; + while (n) { + new = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); + if (!new) { + ksu_ebitmap_destroy(dst); + return -ENOMEM; + } + memset(new, 0, sizeof(ebitmap_node_t)); + new->startbit = n->startbit; + new->map = n->map; + new->next = 0; + if (prev) + prev->next = new; + else + dst->node = new; + prev = new; + n = n->next; + } + + dst->highbit = src->highbit; + return 0; +} + +int ksu_ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2) +{ + const ebitmap_node_t *n1, *n2; + + if (e1->highbit < e2->highbit) + return 0; + + n1 = e1->node; + n2 = e2->node; + while (n1 && n2 && (n1->startbit <= n2->startbit)) { + if (n1->startbit < n2->startbit) { + n1 = n1->next; + continue; + } + if ((n1->map & n2->map) != n2->map) + return 0; + + n1 = n1->next; + n2 = n2->next; + } + + if (n2) + return 0; + + return 1; +} + +int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2) +{ + const ebitmap_node_t *n1 = e1->node; + const ebitmap_node_t *n2 = e2->node; + + while (n1 && n2) { + if (n1->startbit < n2->startbit) { + n1 = n1->next; + } else if (n2->startbit < n1->startbit) { + n2 = n2->next; + } else { + if (n1->map & n2->map) { + return 1; + } + n1 = n1->next; + n2 = n2->next; + } + } + + return 0; +} + +int ksu_ebitmap_get_bit(const ebitmap_t * e, unsigned int bit) +{ + const ebitmap_node_t *n; + + if (e->highbit < bit) + return 0; + + n = e->node; + while (n && (n->startbit <= bit)) { + if ((n->startbit + MAPSIZE) > bit) { + if (n->map & (MAPBIT << (bit - n->startbit))) + return 1; + else + return 0; + } + n = n->next; + } + + return 0; +} + +int ksu_ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value) +{ + ebitmap_node_t *n, *prev, *new; + uint32_t startbit = bit & ~(MAPSIZE - 1); + uint32_t highbit = startbit + MAPSIZE; + + if (highbit == 0) { + ERR(NULL, "bitmap overflow, bit 0x%x", bit); + return -EINVAL; + } + + prev = 0; + n = e->node; + while (n && n->startbit <= bit) { + if ((n->startbit + MAPSIZE) > bit) { + if (value) { + n->map |= (MAPBIT << (bit - n->startbit)); + } else { + n->map &= ~(MAPBIT << (bit - n->startbit)); + if (!n->map) { + /* drop this node from the bitmap */ + + if (!n->next) { + /* + * this was the highest map + * within the bitmap + */ + if (prev) + e->highbit = + prev->startbit + + MAPSIZE; + else + e->highbit = 0; + } + if (prev) + prev->next = n->next; + else + e->node = n->next; + + free(n); + } + } + return 0; + } + prev = n; + n = n->next; + } + + if (!value) + return 0; + + new = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); + if (!new) + return -ENOMEM; + memset(new, 0, sizeof(ebitmap_node_t)); + + new->startbit = startbit; + new->map = (MAPBIT << (bit - new->startbit)); + + if (!n) { + /* this node will be the highest map within the bitmap */ + e->highbit = highbit; + } + + if (prev) { + new->next = prev->next; + prev->next = new; + } else { + new->next = e->node; + e->node = new; + } + + return 0; +} + +unsigned int ebitmap_highest_set_bit(const ebitmap_t * e) +{ + const ebitmap_node_t *n; + MAPTYPE map; + unsigned int pos = 0; + + n = e->node; + if (!n) + return 0; + + while (n->next) + n = n->next; + + map = n->map; + while (map >>= 1) + pos++; + + return n->startbit + pos; +} + +void ksu_ebitmap_destroy(ebitmap_t * e) +{ + ebitmap_node_t *n, *temp; + + if (!e) + return; + + n = e->node; + while (n) { + temp = n; + n = n->next; + free(temp); + } + + e->highbit = 0; + e->node = 0; + return; +} + +int ksu_ebitmap_read(ebitmap_t * e, void *fp) +{ + int rc; + ebitmap_node_t *n, *l; + uint32_t buf[3], mapsize, count, i; + uint64_t map; + + ebitmap_init(e); + + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) + goto bad; + + mapsize = le32_to_cpu(buf[0]); + e->highbit = le32_to_cpu(buf[1]); + count = le32_to_cpu(buf[2]); + + if (mapsize != MAPSIZE) { + ERR(NULL, "security: ebitmap: map size %d does not match my size %zu (high bit was %d)", + mapsize, MAPSIZE, e->highbit); + goto bad; + } + if (!e->highbit) { + e->node = NULL; + goto ok; + } + if (e->highbit & (MAPSIZE - 1)) { + ERR(NULL, "security: ebitmap: high bit (%d) is not a multiple of the map size (%zu)", + e->highbit, MAPSIZE); + goto bad; + } + + if (e->highbit && !count) + goto bad; + + l = NULL; + for (i = 0; i < count; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) { + ERR(NULL, "security: ebitmap: truncated map"); + goto bad; + } + n = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); + if (!n) { + ERR(NULL, "security: ebitmap: out of memory"); + rc = -ENOMEM; + goto bad; + } + memset(n, 0, sizeof(ebitmap_node_t)); + + n->startbit = le32_to_cpu(buf[0]); + + if (n->startbit & (MAPSIZE - 1)) { + ERR(NULL, "security: ebitmap start bit (%d) is not a multiple of the map size (%zu)", + n->startbit, MAPSIZE); + goto bad_free; + } + if (n->startbit > (e->highbit - MAPSIZE)) { + ERR(NULL, "security: ebitmap start bit (%d) is beyond the end of the bitmap (%zu)", + n->startbit, (e->highbit - MAPSIZE)); + goto bad_free; + } + rc = next_entry(&map, fp, sizeof(uint64_t)); + if (rc < 0) { + ERR(NULL, "security: ebitmap: truncated map"); + goto bad_free; + } + n->map = le64_to_cpu(map); + + if (!n->map) { + ERR(NULL, "security: ebitmap: null map in ebitmap (startbit %d)", + n->startbit); + goto bad_free; + } + if (l) { + if (n->startbit <= l->startbit) { + ERR(NULL, "security: ebitmap: start bit %d comes after start bit %d", + n->startbit, l->startbit); + goto bad_free; + } + l->next = n; + } else + e->node = n; + + l = n; + } + if (count && l->startbit + MAPSIZE != e->highbit) { + ERR(NULL, "security: ebitmap: high bit %u has not the expected value %zu", + e->highbit, l->startbit + MAPSIZE); + goto bad; + } + + ok: + rc = 0; + out: + return rc; + bad_free: + free(n); + bad: + if (!rc) + rc = -EINVAL; + ksu_ebitmap_destroy(e); + goto out; +} + +/* FLASK */ diff --git a/kernel/libsepol/src/ebitmap.o b/kernel/libsepol/src/ebitmap.o new file mode 100644 index 00000000..a289dc83 Binary files /dev/null and b/kernel/libsepol/src/ebitmap.o differ diff --git a/kernel/libsepol/src/expand.c b/kernel/libsepol/src/expand.c new file mode 100644 index 00000000..1ea46f87 --- /dev/null +++ b/kernel/libsepol/src/expand.c @@ -0,0 +1,3486 @@ +/* Authors: Karl MacMillan + * Jason Tang + * Joshua Brindle + * + * Copyright (C) 2004-2005 Tresys Technology, LLC + * Copyright (C) 2007 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Technologies, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "context.h" +#include +#include +#include +#include +#include +#include + +// #include +// #include +// #include +#include +// #include +// #include +#include + +#include "debug.h" +#include "private.h" + +typedef struct expand_state { + int verbose; + uint32_t *typemap; + uint32_t *boolmap; + uint32_t *rolemap; + uint32_t *usermap; + policydb_t *base; + policydb_t *out; + sepol_handle_t *handle; + int expand_neverallow; +} expand_state_t; + +static void expand_state_init(expand_state_t * state) +{ + memset(state, 0, sizeof(expand_state_t)); +} + +static int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map) +{ + unsigned int i; + ebitmap_node_t *tnode; + ebitmap_init(dst); + + ebitmap_for_each_positive_bit(src, tnode, i) { + if (!map[i]) + continue; + if (ksu_ebitmap_set_bit(dst, map[i] - 1, 1)) + return -1; + } + return 0; +} + +static int ebitmap_expand_roles(policydb_t *p, ebitmap_t *roles) +{ + ebitmap_node_t *node; + unsigned int bit; + role_datum_t *role; + ebitmap_t tmp; + + ebitmap_init(&tmp); + ebitmap_for_each_positive_bit(roles, node, bit) { + role = p->role_val_to_struct[bit]; + assert(role); + if (role->flavor != ROLE_ATTRIB) { + if (ksu_ebitmap_set_bit(&tmp, bit, 1)) { + ksu_ebitmap_destroy(&tmp); + return -1; + } + } else { + if (ebitmap_union(&tmp, &role->roles)) { + ksu_ebitmap_destroy(&tmp); + return -1; + } + } + } + ksu_ebitmap_destroy(roles); + if (ksu_ebitmap_cpy(roles, &tmp)) { + ksu_ebitmap_destroy(&tmp); + return -1; + } + ksu_ebitmap_destroy(&tmp); + return 0; +} + +static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id, *new_id; + type_datum_t *type, *new_type; + expand_state_t *state; + + id = (char *)key; + type = (type_datum_t *) datum; + state = (expand_state_t *) data; + + if ((type->flavor == TYPE_TYPE && !type->primary) + || type->flavor == TYPE_ALIAS) { + /* aliases are handled later */ + return 0; + } + if (!is_id_enabled(id, state->base, SYM_TYPES)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying type or attribute %s", id); + + new_id = strdup(id); + if (new_id == NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + new_type = (type_datum_t *) malloc(sizeof(type_datum_t)); + if (!new_type) { + ERR(state->handle, "Out of memory!"); + free(new_id); + return SEPOL_ENOMEM; + } + memset(new_type, 0, sizeof(type_datum_t)); + + new_type->flavor = type->flavor; + new_type->flags = type->flags; + new_type->s.value = ++state->out->p_types.nprim; + if (new_type->s.value > UINT16_MAX) { + free(new_id); + free(new_type); + ERR(state->handle, "type space overflow"); + return -1; + } + new_type->primary = 1; + state->typemap[type->s.value - 1] = new_type->s.value; + + ret = hashtab_insert(state->out->p_types.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_type); + if (ret) { + free(new_id); + free(new_type); + ERR(state->handle, "hashtab overflow"); + return -1; + } + + if (new_type->flags & TYPE_FLAGS_PERMISSIVE) + if (ksu_ebitmap_set_bit(&state->out->permissive_map, new_type->s.value, 1)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + return 0; +} + +static int attr_convert_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id; + type_datum_t *type, *new_type; + expand_state_t *state; + ebitmap_t tmp_union; + + id = (char *)key; + type = (type_datum_t *) datum; + state = (expand_state_t *) data; + + if (type->flavor != TYPE_ATTRIB) + return 0; + + if (!is_id_enabled(id, state->base, SYM_TYPES)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "converting attribute %s", id); + + new_type = hashtab_search(state->out->p_types.table, id); + if (!new_type) { + ERR(state->handle, "attribute %s vanished!", id); + return -1; + } + if (map_ebitmap(&type->types, &tmp_union, state->typemap)) { + ERR(state->handle, "out of memory"); + return -1; + } + + /* then union tmp_union onto &new_type->types */ + if (ebitmap_union(&new_type->types, &tmp_union)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + ksu_ebitmap_destroy(&tmp_union); + + return 0; +} + +static int perm_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id, *new_id; + symtab_t *s; + perm_datum_t *perm, *new_perm; + + id = key; + perm = (perm_datum_t *) datum; + s = (symtab_t *) data; + + new_perm = (perm_datum_t *) malloc(sizeof(perm_datum_t)); + if (!new_perm) { + return -1; + } + memset(new_perm, 0, sizeof(perm_datum_t)); + + new_id = strdup(id); + if (!new_id) { + free(new_perm); + return -1; + } + + new_perm->s.value = perm->s.value; + s->nprim++; + + ret = hashtab_insert(s->table, new_id, (hashtab_datum_t) new_perm); + if (ret) { + free(new_id); + free(new_perm); + return -1; + } + + return 0; +} + +static int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id, *new_id; + common_datum_t *common, *new_common; + expand_state_t *state; + + id = (char *)key; + common = (common_datum_t *) datum; + state = (expand_state_t *) data; + + if (state->verbose) + INFO(state->handle, "copying common %s", id); + + new_common = (common_datum_t *) malloc(sizeof(common_datum_t)); + if (!new_common) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(new_common, 0, sizeof(common_datum_t)); + if (ksu_symtab_init(&new_common->permissions, PERM_SYMTAB_SIZE)) { + ERR(state->handle, "Out of memory!"); + free(new_common); + return -1; + } + + new_id = strdup(id); + if (!new_id) { + ERR(state->handle, "Out of memory!"); + /* free memory created by ksu_symtab_init first, then free new_common */ + symtab_destroy(&new_common->permissions); + free(new_common); + return -1; + } + + new_common->s.value = common->s.value; + state->out->p_commons.nprim++; + + ret = + hashtab_insert(state->out->p_commons.table, new_id, + (hashtab_datum_t) new_common); + if (ret) { + ERR(state->handle, "hashtab overflow"); + free(new_common); + free(new_id); + return -1; + } + + if (ksu_hashtab_map + (common->permissions.table, perm_copy_callback, + &new_common->permissions)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + return 0; +} + +static int constraint_node_clone(constraint_node_t ** dst, + constraint_node_t * src, + expand_state_t * state) +{ + constraint_node_t *new_con = NULL, *last_new_con = NULL; + constraint_expr_t *new_expr = NULL; + *dst = NULL; + while (src != NULL) { + constraint_expr_t *expr, *expr_l = NULL; + new_con = + (constraint_node_t *) malloc(sizeof(constraint_node_t)); + if (!new_con) { + goto out_of_mem; + } + memset(new_con, 0, sizeof(constraint_node_t)); + new_con->permissions = src->permissions; + for (expr = src->expr; expr; expr = expr->next) { + if ((new_expr = calloc(1, sizeof(*new_expr))) == NULL) { + goto out_of_mem; + } + if (constraint_expr_init(new_expr) == -1) { + goto out_of_mem; + } + new_expr->expr_type = expr->expr_type; + new_expr->attr = expr->attr; + new_expr->op = expr->op; + if (new_expr->expr_type == CEXPR_NAMES) { + if (new_expr->attr & CEXPR_TYPE) { + /* + * Copy over constraint policy source types and/or + * attributes for sepol_compute_av_reason_buffer(3) + * so that utilities can analyse constraint errors. + */ + if (map_ebitmap(&expr->type_names->types, + &new_expr->type_names->types, + state->typemap)) { + ERR(NULL, "Failed to map type_names->types"); + goto out_of_mem; + } + /* Type sets require expansion and conversion. */ + if (expand_convert_type_set(state->out, + state-> + typemap, + expr-> + type_names, + &new_expr-> + names, 1)) { + goto out_of_mem; + } + } else if (new_expr->attr & CEXPR_ROLE) { + if (map_ebitmap(&expr->names, &new_expr->names, state->rolemap)) { + goto out_of_mem; + } + if (ebitmap_expand_roles(state->out, &new_expr->names)) { + goto out_of_mem; + } + } else if (new_expr->attr & CEXPR_USER) { + if (map_ebitmap(&expr->names, &new_expr->names, state->usermap)) { + goto out_of_mem; + } + } else { + /* Other kinds of sets do not. */ + if (ksu_ebitmap_cpy(&new_expr->names, + &expr->names)) { + goto out_of_mem; + } + } + } + if (expr_l) { + expr_l->next = new_expr; + } else { + new_con->expr = new_expr; + } + expr_l = new_expr; + new_expr = NULL; + } + if (last_new_con == NULL) { + *dst = new_con; + } else { + last_new_con->next = new_con; + } + last_new_con = new_con; + src = src->next; + } + + return 0; + out_of_mem: + ERR(state->handle, "Out of memory!"); + if (new_con) + free(new_con); + constraint_expr_destroy(new_expr); + return -1; +} + +static int class_copy_default_new_object(expand_state_t *state, + class_datum_t *olddatum, + class_datum_t *newdatum) +{ + if (olddatum->default_user) { + if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { + ERR(state->handle, "Found conflicting default user definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_user = olddatum->default_user; + + } + if (olddatum->default_role) { + if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { + ERR(state->handle, "Found conflicting default role definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_role = olddatum->default_role; + } + if (olddatum->default_type) { + if (newdatum->default_type && olddatum->default_type != newdatum->default_type) { + ERR(state->handle, "Found conflicting default type definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_type = olddatum->default_type; + } + if (olddatum->default_range) { + if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { + ERR(state->handle, "Found conflicting default range definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_range = olddatum->default_range; + } + return 0; +} + +static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id, *new_id; + class_datum_t *class, *new_class; + expand_state_t *state; + + id = (char *)key; + class = (class_datum_t *) datum; + state = (expand_state_t *) data; + + if (!is_id_enabled(id, state->base, SYM_CLASSES)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying class %s", id); + + new_class = (class_datum_t *) malloc(sizeof(class_datum_t)); + if (!new_class) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(new_class, 0, sizeof(class_datum_t)); + if (ksu_symtab_init(&new_class->permissions, PERM_SYMTAB_SIZE)) { + ERR(state->handle, "Out of memory!"); + free(new_class); + return -1; + } + + new_class->s.value = class->s.value; + state->out->p_classes.nprim++; + + ret = class_copy_default_new_object(state, class, new_class); + if (ret) { + free(new_class); + return ret; + } + + new_id = strdup(id); + if (!new_id) { + ERR(state->handle, "Out of memory!"); + free(new_class); + return -1; + } + + ret = + hashtab_insert(state->out->p_classes.table, new_id, + (hashtab_datum_t) new_class); + if (ret) { + ERR(state->handle, "hashtab overflow"); + free(new_class); + free(new_id); + return -1; + } + + if (ksu_hashtab_map + (class->permissions.table, perm_copy_callback, + &new_class->permissions)) { + ERR(state->handle, "hashtab overflow"); + return -1; + } + + if (class->comkey) { + new_class->comkey = strdup(class->comkey); + if (!new_class->comkey) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + new_class->comdatum = + hashtab_search(state->out->p_commons.table, + new_class->comkey); + if (!new_class->comdatum) { + ERR(state->handle, "could not find common datum %s", + new_class->comkey); + return -1; + } + new_class->permissions.nprim += + new_class->comdatum->permissions.nprim; + } + + return 0; +} + +static int constraint_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id; + class_datum_t *class, *new_class; + expand_state_t *state; + + id = (char *)key; + class = (class_datum_t *) datum; + state = (expand_state_t *) data; + + new_class = hashtab_search(state->out->p_classes.table, id); + if (!new_class) { + ERR(state->handle, "class %s vanished", id); + return -1; + } + + /* constraints */ + if (constraint_node_clone + (&new_class->constraints, class->constraints, state) == -1 + || constraint_node_clone(&new_class->validatetrans, + class->validatetrans, state) == -1) { + return -1; + } + return 0; +} + +/* + * The boundaries have to be copied after the types/roles/users are copied, + * because it refers hashtab to lookup destinated objects. + */ +static int type_bounds_copy_callback(hashtab_key_t key, + hashtab_datum_t datum, void *data) +{ + expand_state_t *state = (expand_state_t *) data; + type_datum_t *type = (type_datum_t *) datum; + type_datum_t *dest; + uint32_t bounds_val; + + if (!type->bounds) + return 0; + + if (!is_id_enabled((char *)key, state->base, SYM_TYPES)) + return 0; + + bounds_val = state->typemap[type->bounds - 1]; + + dest = hashtab_search(state->out->p_types.table, (char *)key); + if (!dest) { + ERR(state->handle, "Type lookup failed for %s", (char *)key); + return -1; + } + if (dest->bounds != 0 && dest->bounds != bounds_val) { + ERR(state->handle, "Inconsistent boundary for %s", (char *)key); + return -1; + } + dest->bounds = bounds_val; + + return 0; +} + +static int role_bounds_copy_callback(hashtab_key_t key, + hashtab_datum_t datum, void *data) +{ + expand_state_t *state = (expand_state_t *) data; + role_datum_t *role = (role_datum_t *) datum; + role_datum_t *dest; + uint32_t bounds_val; + + if (!role->bounds) + return 0; + + if (!is_id_enabled((char *)key, state->base, SYM_ROLES)) + return 0; + + bounds_val = state->rolemap[role->bounds - 1]; + + dest = hashtab_search(state->out->p_roles.table, (char *)key); + if (!dest) { + ERR(state->handle, "Role lookup failed for %s", (char *)key); + return -1; + } + if (dest->bounds != 0 && dest->bounds != bounds_val) { + ERR(state->handle, "Inconsistent boundary for %s", (char *)key); + return -1; + } + dest->bounds = bounds_val; + + return 0; +} + +static int user_bounds_copy_callback(hashtab_key_t key, + hashtab_datum_t datum, void *data) +{ + expand_state_t *state = (expand_state_t *) data; + user_datum_t *user = (user_datum_t *) datum; + user_datum_t *dest; + uint32_t bounds_val; + + if (!user->bounds) + return 0; + + if (!is_id_enabled((char *)key, state->base, SYM_USERS)) + return 0; + + bounds_val = state->usermap[user->bounds - 1]; + + dest = hashtab_search(state->out->p_users.table, (char *)key); + if (!dest) { + ERR(state->handle, "User lookup failed for %s", (char *)key); + return -1; + } + if (dest->bounds != 0 && dest->bounds != bounds_val) { + ERR(state->handle, "Inconsistent boundary for %s", (char *)key); + return -1; + } + dest->bounds = bounds_val; + + return 0; +} + +/* The aliases have to be copied after the types and attributes to be certain that + * the out symbol table will have the type that the alias refers. Otherwise, we + * won't be able to find the type value for the alias. We can't depend on the + * declaration ordering because of the hash table. + */ +static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id, *new_id; + type_datum_t *alias, *new_alias; + expand_state_t *state; + uint32_t prival; + + id = (char *)key; + alias = (type_datum_t *) datum; + state = (expand_state_t *) data; + + /* ignore regular types */ + if (alias->flavor == TYPE_TYPE && alias->primary) + return 0; + + /* ignore attributes */ + if (alias->flavor == TYPE_ATTRIB) + return 0; + + if (alias->flavor == TYPE_ALIAS) + prival = alias->primary; + else + prival = alias->s.value; + + if (!is_id_enabled(state->base->p_type_val_to_name[prival - 1], + state->base, SYM_TYPES)) { + /* The primary type for this alias is not enabled, the alias + * shouldn't be either */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying alias %s", id); + + new_id = strdup(id); + if (!new_id) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + new_alias = (type_datum_t *) malloc(sizeof(type_datum_t)); + if (!new_alias) { + ERR(state->handle, "Out of memory!"); + free(new_id); + return SEPOL_ENOMEM; + } + memset(new_alias, 0, sizeof(type_datum_t)); + if (alias->flavor == TYPE_TYPE) + new_alias->s.value = state->typemap[alias->s.value - 1]; + else if (alias->flavor == TYPE_ALIAS) + new_alias->s.value = state->typemap[alias->primary - 1]; + else + assert(0); /* unreachable */ + + new_alias->flags = alias->flags; + + ret = hashtab_insert(state->out->p_types.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_alias); + + if (ret) { + ERR(state->handle, "hashtab overflow"); + free(new_alias); + free(new_id); + return -1; + } + + state->typemap[alias->s.value - 1] = new_alias->s.value; + + if (new_alias->flags & TYPE_FLAGS_PERMISSIVE) + if (ksu_ebitmap_set_bit(&state->out->permissive_map, new_alias->s.value, 1)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + return 0; +} + +static int role_remap_dominates(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *data) +{ + ebitmap_t mapped_roles; + role_datum_t *role = (role_datum_t *) datum; + expand_state_t *state = (expand_state_t *) data; + + if (map_ebitmap(&role->dominates, &mapped_roles, state->rolemap)) + return -1; + + ksu_ebitmap_destroy(&role->dominates); + + if (ksu_ebitmap_cpy(&role->dominates, &mapped_roles)) + return -1; + + ksu_ebitmap_destroy(&mapped_roles); + + return 0; +} + +/* For the role attribute in the base module, escalate its counterpart's + * types.types ebitmap in the out module to the counterparts of all the + * regular role that belongs to the current role attribute. Note, must be + * invoked after role_copy_callback so that state->rolemap is available. + */ +static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id, *base_reg_role_id; + role_datum_t *role, *new_role, *regular_role; + expand_state_t *state; + ebitmap_node_t *rnode; + unsigned int i; + ebitmap_t mapped_roles; + + id = key; + role = (role_datum_t *)datum; + state = (expand_state_t *)data; + + if (strcmp(id, OBJECT_R) == 0) { + /* object_r is never a role attribute by far */ + return 0; + } + + if (!is_id_enabled(id, state->base, SYM_ROLES)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (role->flavor != ROLE_ATTRIB) + return 0; + + if (state->verbose) + INFO(state->handle, "fixing role attribute %s", id); + + new_role = + (role_datum_t *)hashtab_search(state->out->p_roles.table, id); + + assert(new_role != NULL && new_role->flavor == ROLE_ATTRIB); + + ebitmap_init(&mapped_roles); + if (map_ebitmap(&role->roles, &mapped_roles, state->rolemap)) + return -1; + if (ebitmap_union(&new_role->roles, &mapped_roles)) { + ERR(state->handle, "Out of memory!"); + ksu_ebitmap_destroy(&mapped_roles); + return -1; + } + ksu_ebitmap_destroy(&mapped_roles); + + ebitmap_for_each_positive_bit(&role->roles, rnode, i) { + /* take advantage of sym_val_to_name[] + * of the base module */ + base_reg_role_id = state->base->p_role_val_to_name[i]; + regular_role = (role_datum_t *)hashtab_search( + state->out->p_roles.table, + base_reg_role_id); + assert(regular_role != NULL && + regular_role->flavor == ROLE_ROLE); + + if (ebitmap_union(®ular_role->types.types, + &new_role->types.types)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + } + + return 0; +} + +static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id, *new_id; + role_datum_t *role; + role_datum_t *new_role; + expand_state_t *state; + ebitmap_t tmp_union_types; + + id = key; + role = (role_datum_t *) datum; + state = (expand_state_t *) data; + + if (strcmp(id, OBJECT_R) == 0) { + /* object_r is always value 1 */ + state->rolemap[role->s.value - 1] = 1; + return 0; + } + + if (!is_id_enabled(id, state->base, SYM_ROLES)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying role %s", id); + + new_role = + (role_datum_t *) hashtab_search(state->out->p_roles.table, id); + if (!new_role) { + new_role = (role_datum_t *) malloc(sizeof(role_datum_t)); + if (!new_role) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(new_role, 0, sizeof(role_datum_t)); + + new_id = strdup(id); + if (!new_id) { + ERR(state->handle, "Out of memory!"); + free(new_role); + return -1; + } + + state->out->p_roles.nprim++; + new_role->flavor = role->flavor; + new_role->s.value = state->out->p_roles.nprim; + state->rolemap[role->s.value - 1] = new_role->s.value; + ret = hashtab_insert(state->out->p_roles.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_role); + + if (ret) { + ERR(state->handle, "hashtab overflow"); + free(new_role); + free(new_id); + return -1; + } + } + + /* The dominates bitmap is going to be wrong for the moment, + * we'll come back later and remap them, after we are sure all + * the roles have been added */ + if (ebitmap_union(&new_role->dominates, &role->dominates)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + ebitmap_init(&tmp_union_types); + + /* convert types in the role datum in the global symtab */ + if (expand_convert_type_set + (state->out, state->typemap, &role->types, &tmp_union_types, 1)) { + ksu_ebitmap_destroy(&tmp_union_types); + ERR(state->handle, "Out of memory!"); + return -1; + } + + if (ebitmap_union(&new_role->types.types, &tmp_union_types)) { + ERR(state->handle, "Out of memory!"); + ksu_ebitmap_destroy(&tmp_union_types); + return -1; + } + ksu_ebitmap_destroy(&tmp_union_types); + + return 0; +} + +int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l, + policydb_t * p, sepol_handle_t * h) +{ + mls_semantic_cat_t *cat; + level_datum_t *levdatum; + unsigned int i; + + mls_level_init(l); + + if (!p->mls) + return 0; + + /* Required not declared. */ + if (!sl->sens) + return 0; + + /* Invalid sensitivity */ + if (sl->sens > p->p_levels.nprim || !p->p_sens_val_to_name[sl->sens - 1]) + return -1; + + l->sens = sl->sens; + levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, + p->p_sens_val_to_name[l->sens - 1]); + if (!levdatum) { + ERR(h, "%s: Impossible situation found, nothing in p_levels.table.", + __func__); + // errno = ENOENT; + return -1; + } + for (cat = sl->cat; cat; cat = cat->next) { + if (cat->low > cat->high) { + ERR(h, "Category range is not valid %s.%s", + p->p_cat_val_to_name[cat->low - 1], + p->p_cat_val_to_name[cat->high - 1]); + return -1; + } + for (i = cat->low - 1; i < cat->high; i++) { + if (!ksu_ebitmap_get_bit(&levdatum->level->cat, i)) { + ERR(h, "Category %s can not be associated with " + "level %s", + p->p_cat_val_to_name[i], + p->p_sens_val_to_name[l->sens - 1]); + return -1; + } + if (ksu_ebitmap_set_bit(&l->cat, i, 1)) { + ERR(h, "Out of memory!"); + return -1; + } + } + } + + return 0; +} + +int mls_semantic_range_expand(mls_semantic_range_t * sr, mls_range_t * r, + policydb_t * p, sepol_handle_t * h) +{ + if (mls_semantic_level_expand(&sr->level[0], &r->level[0], p, h) < 0) + return -1; + + if (mls_semantic_level_expand(&sr->level[1], &r->level[1], p, h) < 0) { + mls_level_destroy(&r->level[0]); + return -1; + } + + if (!mls_level_dom(&r->level[1], &r->level[0])) { + mls_range_destroy(r); + ERR(h, "MLS range high level does not dominate low level"); + return -1; + } + + return 0; +} + +static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + expand_state_t *state; + user_datum_t *user; + user_datum_t *new_user; + char *id, *new_id; + ebitmap_t tmp_union; + + id = key; + user = (user_datum_t *) datum; + state = (expand_state_t *) data; + + if (!is_id_enabled(id, state->base, SYM_USERS)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying user %s", id); + + new_user = + (user_datum_t *) hashtab_search(state->out->p_users.table, id); + if (!new_user) { + new_user = (user_datum_t *) malloc(sizeof(user_datum_t)); + if (!new_user) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(new_user, 0, sizeof(user_datum_t)); + + state->out->p_users.nprim++; + new_user->s.value = state->out->p_users.nprim; + state->usermap[user->s.value - 1] = new_user->s.value; + + new_id = strdup(id); + if (!new_id) { + ERR(state->handle, "Out of memory!"); + free(new_user); + return -1; + } + ret = hashtab_insert(state->out->p_users.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_user); + if (ret) { + ERR(state->handle, "hashtab overflow"); + user_datum_destroy(new_user); + free(new_user); + free(new_id); + return -1; + } + + /* expand the semantic MLS info */ + if (mls_semantic_range_expand(&user->range, + &new_user->exp_range, + state->out, state->handle)) { + return -1; + } + if (mls_semantic_level_expand(&user->dfltlevel, + &new_user->exp_dfltlevel, + state->out, state->handle)) { + return -1; + } + if (!mls_level_between(&new_user->exp_dfltlevel, + &new_user->exp_range.level[0], + &new_user->exp_range.level[1])) { + ERR(state->handle, "default level not within user " + "range"); + return -1; + } + } else { + /* require that the MLS info match */ + mls_range_t tmp_range; + mls_level_t tmp_level; + + if (mls_semantic_range_expand(&user->range, &tmp_range, + state->out, state->handle)) { + return -1; + } + if (mls_semantic_level_expand(&user->dfltlevel, &tmp_level, + state->out, state->handle)) { + mls_range_destroy(&tmp_range); + return -1; + } + if (!mls_range_eq(&new_user->exp_range, &tmp_range) || + !mls_level_eq(&new_user->exp_dfltlevel, &tmp_level)) { + mls_range_destroy(&tmp_range); + mls_level_destroy(&tmp_level); + return -1; + } + mls_range_destroy(&tmp_range); + mls_level_destroy(&tmp_level); + } + + ebitmap_init(&tmp_union); + + /* get global roles for this user */ + if (role_set_expand(&user->roles, &tmp_union, state->out, state->base, state->rolemap)) { + ERR(state->handle, "Out of memory!"); + ksu_ebitmap_destroy(&tmp_union); + return -1; + } + + if (ebitmap_union(&new_user->roles.roles, &tmp_union)) { + ERR(state->handle, "Out of memory!"); + ksu_ebitmap_destroy(&tmp_union); + return -1; + } + ksu_ebitmap_destroy(&tmp_union); + + return 0; +} + +static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + expand_state_t *state; + cond_bool_datum_t *bool, *new_bool; + char *id, *new_id; + + id = key; + bool = (cond_bool_datum_t *) datum; + state = (expand_state_t *) data; + + if (!is_id_enabled(id, state->base, SYM_BOOLS)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (bool->flags & COND_BOOL_FLAGS_TUNABLE) { + /* Skip tunables */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying boolean %s", id); + + new_bool = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); + if (!new_bool) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + new_id = strdup(id); + if (!new_id) { + ERR(state->handle, "Out of memory!"); + free(new_bool); + return -1; + } + + state->out->p_bools.nprim++; + new_bool->s.value = state->out->p_bools.nprim; + + ret = hashtab_insert(state->out->p_bools.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_bool); + if (ret) { + ERR(state->handle, "hashtab overflow"); + free(new_bool); + free(new_id); + return -1; + } + + state->boolmap[bool->s.value - 1] = new_bool->s.value; + + new_bool->state = bool->state; + new_bool->flags = bool->flags; + + return 0; +} + +static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + expand_state_t *state = (expand_state_t *) data; + level_datum_t *level = (level_datum_t *) datum, *new_level = NULL; + char *id = (char *)key, *new_id = NULL; + + if (!is_id_enabled(id, state->base, SYM_LEVELS)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying sensitivity level %s", id); + + new_level = (level_datum_t *) malloc(sizeof(level_datum_t)); + if (!new_level) + goto out_of_mem; + level_datum_init(new_level); + new_level->level = (mls_level_t *) malloc(sizeof(mls_level_t)); + if (!new_level->level) + goto out_of_mem; + mls_level_init(new_level->level); + new_id = strdup(id); + if (!new_id) + goto out_of_mem; + + if (mls_level_cpy(new_level->level, level->level)) { + goto out_of_mem; + } + new_level->isalias = level->isalias; + state->out->p_levels.nprim++; + + if (hashtab_insert(state->out->p_levels.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_level)) { + goto out_of_mem; + } + return 0; + + out_of_mem: + ERR(state->handle, "Out of memory!"); + if (new_level != NULL && new_level->level != NULL) { + mls_level_destroy(new_level->level); + free(new_level->level); + } + level_datum_destroy(new_level); + free(new_level); + free(new_id); + return -1; +} + +static int cats_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + expand_state_t *state = (expand_state_t *) data; + cat_datum_t *cat = (cat_datum_t *) datum, *new_cat = NULL; + char *id = (char *)key, *new_id = NULL; + + if (!is_id_enabled(id, state->base, SYM_CATS)) { + /* identifier's scope is not enabled */ + return 0; + } + + if (state->verbose) + INFO(state->handle, "copying category attribute %s", id); + + new_cat = (cat_datum_t *) malloc(sizeof(cat_datum_t)); + if (!new_cat) + goto out_of_mem; + cat_datum_init(new_cat); + new_id = strdup(id); + if (!new_id) + goto out_of_mem; + + new_cat->s.value = cat->s.value; + new_cat->isalias = cat->isalias; + state->out->p_cats.nprim++; + if (hashtab_insert(state->out->p_cats.table, + (hashtab_key_t) new_id, (hashtab_datum_t) new_cat)) { + goto out_of_mem; + } + + return 0; + + out_of_mem: + ERR(state->handle, "Out of memory!"); + cat_datum_destroy(new_cat); + free(new_cat); + free(new_id); + return -1; +} + +static int copy_role_allows(expand_state_t * state, role_allow_rule_t * rules) +{ + unsigned int i, j; + role_allow_t *cur_allow, *n, *l; + role_allow_rule_t *cur; + ebitmap_t roles, new_roles; + ebitmap_node_t *snode, *tnode; + + /* start at the end of the list */ + for (l = state->out->role_allow; l && l->next; l = l->next) ; + + cur = rules; + while (cur) { + ebitmap_init(&roles); + ebitmap_init(&new_roles); + + if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + if (role_set_expand(&cur->new_roles, &new_roles, state->out, state->base, state->rolemap)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + ebitmap_for_each_positive_bit(&roles, snode, i) { + ebitmap_for_each_positive_bit(&new_roles, tnode, j) { + /* check for duplicates */ + cur_allow = state->out->role_allow; + while (cur_allow) { + if ((cur_allow->role == i + 1) && + (cur_allow->new_role == j + 1)) + break; + cur_allow = cur_allow->next; + } + if (cur_allow) + continue; + n = (role_allow_t *) + malloc(sizeof(role_allow_t)); + if (!n) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(n, 0, sizeof(role_allow_t)); + n->role = i + 1; + n->new_role = j + 1; + if (l) { + l->next = n; + } else { + state->out->role_allow = n; + } + l = n; + } + } + + ksu_ebitmap_destroy(&roles); + ksu_ebitmap_destroy(&new_roles); + + cur = cur->next; + } + + return 0; +} + +static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules) +{ + unsigned int i, j, k; + role_trans_t *n, *l, *cur_trans; + role_trans_rule_t *cur; + ebitmap_t roles, types; + ebitmap_node_t *rnode, *tnode, *cnode; + + /* start at the end of the list */ + for (l = state->out->role_tr; l && l->next; l = l->next) ; + + cur = rules; + while (cur) { + ebitmap_init(&roles); + ebitmap_init(&types); + + if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + if (expand_convert_type_set + (state->out, state->typemap, &cur->types, &types, 1)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + ebitmap_for_each_positive_bit(&roles, rnode, i) { + ebitmap_for_each_positive_bit(&types, tnode, j) { + ebitmap_for_each_positive_bit(&cur->classes, cnode, k) { + cur_trans = state->out->role_tr; + while (cur_trans) { + unsigned int mapped_role; + + mapped_role = state->rolemap[cur->new_role - 1]; + + if ((cur_trans->role == + i + 1) && + (cur_trans->type == + j + 1) && + (cur_trans->tclass == + k + 1)) { + if (cur_trans->new_role == mapped_role) { + break; + } else { + ERR(state->handle, + "Conflicting role trans rule %s %s : %s { %s vs %s }", + state->out->p_role_val_to_name[i], + state->out->p_type_val_to_name[j], + state->out->p_class_val_to_name[k], + state->out->p_role_val_to_name[mapped_role - 1], + state->out->p_role_val_to_name[cur_trans->new_role - 1]); + return -1; + } + } + cur_trans = cur_trans->next; + } + if (cur_trans) + continue; + + n = (role_trans_t *) + malloc(sizeof(role_trans_t)); + if (!n) { + ERR(state->handle, + "Out of memory!"); + return -1; + } + memset(n, 0, sizeof(role_trans_t)); + n->role = i + 1; + n->type = j + 1; + n->tclass = k + 1; + n->new_role = state->rolemap + [cur->new_role - 1]; + if (l) + l->next = n; + else + state->out->role_tr = n; + + l = n; + } + } + } + + ksu_ebitmap_destroy(&roles); + ksu_ebitmap_destroy(&types); + + cur = cur->next; + } + return 0; +} + +static int expand_filename_trans_helper(expand_state_t *state, + filename_trans_rule_t *rule, + unsigned int s, unsigned int t) +{ + uint32_t mapped_otype, present_otype; + int rc; + + mapped_otype = state->typemap[rule->otype - 1]; + + rc = policydb_filetrans_insert( + state->out, s + 1, t + 1, + rule->tclass, rule->name, + NULL, mapped_otype, &present_otype + ); + if (rc == SEPOL_EEXIST) { + /* duplicate rule, ignore */ + if (present_otype == mapped_otype) + return 0; + + ERR(state->handle, "Conflicting name-based type_transition %s %s:%s \"%s\": %s vs %s", + state->out->p_type_val_to_name[s], + state->out->p_type_val_to_name[t], + state->out->p_class_val_to_name[rule->tclass - 1], + rule->name, + state->out->p_type_val_to_name[present_otype - 1], + state->out->p_type_val_to_name[mapped_otype - 1]); + return -1; + } else if (rc < 0) { + ERR(state->handle, "Out of memory!"); + return -1; + } + return 0; +} + +static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules) +{ + unsigned int i, j; + filename_trans_rule_t *cur_rule; + ebitmap_t stypes, ttypes; + ebitmap_node_t *snode, *tnode; + int rc; + + cur_rule = rules; + while (cur_rule) { + ebitmap_init(&stypes); + ebitmap_init(&ttypes); + + if (expand_convert_type_set(state->out, state->typemap, + &cur_rule->stypes, &stypes, 1)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + if (expand_convert_type_set(state->out, state->typemap, + &cur_rule->ttypes, &ttypes, 1)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + + ebitmap_for_each_positive_bit(&stypes, snode, i) { + ebitmap_for_each_positive_bit(&ttypes, tnode, j) { + rc = expand_filename_trans_helper( + state, cur_rule, i, j + ); + if (rc) + return rc; + } + if (cur_rule->flags & RULE_SELF) { + rc = expand_filename_trans_helper( + state, cur_rule, i, i + ); + if (rc) + return rc; + } + } + + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&ttypes); + + cur_rule = cur_rule->next; + } + return 0; +} + +static int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t tclass, + mls_semantic_range_t * trange, + expand_state_t * state) +{ + range_trans_t *rt = NULL, key; + mls_range_t *r, *exp_range = NULL; + int rc = -1; + + exp_range = calloc(1, sizeof(*exp_range)); + if (!exp_range) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + if (mls_semantic_range_expand(trange, exp_range, state->out, + state->handle)) + goto err; + + /* check for duplicates/conflicts */ + key.source_type = stype; + key.target_type = ttype; + key.target_class = tclass; + r = hashtab_search(state->out->range_tr, (hashtab_key_t) &key); + if (r) { + if (mls_range_eq(r, exp_range)) { + /* duplicate, ignore */ + mls_range_destroy(exp_range); + free(exp_range); + return 0; + } + + /* conflict */ + ERR(state->handle, + "Conflicting range trans rule %s %s : %s", + state->out->p_type_val_to_name[stype - 1], + state->out->p_type_val_to_name[ttype - 1], + state->out->p_class_val_to_name[tclass - 1]); + goto err; + } + + rt = calloc(1, sizeof(*rt)); + if (!rt) { + ERR(state->handle, "Out of memory!"); + goto err; + } + rt->source_type = stype; + rt->target_type = ttype; + rt->target_class = tclass; + + rc = hashtab_insert(state->out->range_tr, (hashtab_key_t) rt, + exp_range); + if (rc) { + ERR(state->handle, "Out of memory!"); + goto err; + + } + + return 0; +err: + free(rt); + if (exp_range) { + mls_range_destroy(exp_range); + free(exp_range); + } + return -1; +} + +static int expand_range_trans(expand_state_t * state, + range_trans_rule_t * rules) +{ + unsigned int i, j, k; + range_trans_rule_t *rule; + + ebitmap_t stypes, ttypes; + ebitmap_node_t *snode, *tnode, *cnode; + + if (state->verbose) + INFO(state->handle, "expanding range transitions"); + + for (rule = rules; rule; rule = rule->next) { + ebitmap_init(&stypes); + ebitmap_init(&ttypes); + + /* expand the type sets */ + if (expand_convert_type_set(state->out, state->typemap, + &rule->stypes, &stypes, 1)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + if (expand_convert_type_set(state->out, state->typemap, + &rule->ttypes, &ttypes, 1)) { + ksu_ebitmap_destroy(&stypes); + ERR(state->handle, "Out of memory!"); + return -1; + } + + /* loop on source type */ + ebitmap_for_each_positive_bit(&stypes, snode, i) { + /* loop on target type */ + ebitmap_for_each_positive_bit(&ttypes, tnode, j) { + /* loop on target class */ + ebitmap_for_each_positive_bit(&rule->tclasses, cnode, k) { + if (exp_rangetr_helper(i + 1, + j + 1, + k + 1, + &rule->trange, + state)) { + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&ttypes); + return -1; + } + } + } + } + + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&ttypes); + } + + return 0; +} + +/* Search for an AV tab node within a hash table with the given key. + * If the node does not exist, create it and return it; otherwise + * return the pre-existing one. +*/ +static avtab_ptr_t find_avtab_node(sepol_handle_t * handle, + avtab_t * avtab, avtab_key_t * key, + cond_av_list_t ** cond, + av_extended_perms_t *xperms) +{ + avtab_ptr_t node; + avtab_datum_t avdatum; + cond_av_list_t *nl; + int match = 0; + + /* AVTAB_XPERMS entries are not necessarily unique */ + if (key->specified & AVTAB_XPERMS) { + if (xperms == NULL) { + ERR(handle, "searching xperms NULL"); + node = NULL; + } else { + node = ksu_avtab_search_node(avtab, key); + while (node) { + if ((node->datum.xperms->specified == xperms->specified) && + (node->datum.xperms->driver == xperms->driver)) { + match = 1; + break; + } + node = ksu_avtab_search_node_next(node, key->specified); + } + if (!match) + node = NULL; + } + } else { + node = ksu_avtab_search_node(avtab, key); + } + + /* If this is for conditional policies, keep searching in case + the node is part of my conditional avtab. */ + if (cond) { + while (node) { + if (node->parse_context == cond) + break; + node = ksu_avtab_search_node_next(node, key->specified); + } + } + + if (!node) { + memset(&avdatum, 0, sizeof avdatum); + /* + * AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for + * others. Initialize the data accordingly. + */ + avdatum.data = key->specified == AVTAB_AUDITDENY ? ~UINT32_C(0) : UINT32_C(0); + /* this is used to get the node - insertion is actually unique */ + node = ksu_avtab_insert_nonunique(avtab, key, &avdatum); + if (!node) { + ERR(handle, "hash table overflow"); + return NULL; + } + if (cond) { + node->parse_context = cond; + nl = (cond_av_list_t *) malloc(sizeof(cond_av_list_t)); + if (!nl) { + ERR(handle, "Memory error"); + return NULL; + } + memset(nl, 0, sizeof(cond_av_list_t)); + nl->node = node; + nl->next = *cond; + *cond = nl; + } + } + + return node; +} + +static uint32_t avrule_to_avtab_spec(uint32_t specification) +{ + return (specification == AVRULE_DONTAUDIT) ? + AVTAB_AUDITDENY : specification; +} + +#define EXPAND_RULE_SUCCESS 1 +#define EXPAND_RULE_CONFLICT 0 +#define EXPAND_RULE_ERROR -1 + +static int expand_terule_helper(sepol_handle_t * handle, + policydb_t * p, uint32_t * typemap, + uint32_t specified, cond_av_list_t ** cond, + cond_av_list_t ** other, uint32_t stype, + uint32_t ttype, class_perm_node_t * perms, + avtab_t * avtab, int enabled) +{ + avtab_key_t avkey; + avtab_datum_t *avdatump; + avtab_ptr_t node; + class_perm_node_t *cur; + int conflict; + uint32_t oldtype = 0; + + if (!(specified & (AVRULE_TRANSITION|AVRULE_MEMBER|AVRULE_CHANGE))) { + ERR(handle, "Invalid specification: %"PRIu32, specified); + return EXPAND_RULE_ERROR; + } + + avkey.specified = avrule_to_avtab_spec(specified); + avkey.source_type = stype + 1; + avkey.target_type = ttype + 1; + + cur = perms; + while (cur) { + uint32_t remapped_data = + typemap ? typemap[cur->data - 1] : cur->data; + avkey.target_class = cur->tclass; + + conflict = 0; + /* check to see if the expanded TE already exists -- + * either in the global scope or in another + * conditional AV tab */ + node = ksu_avtab_search_node(&p->te_avtab, &avkey); + if (node) { + conflict = 1; + } else { + node = ksu_avtab_search_node(&p->te_cond_avtab, &avkey); + if (node && node->parse_context != other) { + conflict = 2; + } + } + + if (conflict) { + avdatump = &node->datum; + if (specified & AVRULE_TRANSITION) { + oldtype = avdatump->data; + } else if (specified & AVRULE_MEMBER) { + oldtype = avdatump->data; + } else if (specified & AVRULE_CHANGE) { + oldtype = avdatump->data; + } + + if (oldtype == remapped_data) { + /* if the duplicate is inside the same scope (eg., unconditional + * or in same conditional then ignore it */ + if ((conflict == 1 && cond == NULL) + || node->parse_context == cond) + return EXPAND_RULE_SUCCESS; + ERR(handle, "duplicate TE rule for %s %s:%s %s", + p->p_type_val_to_name[avkey.source_type - + 1], + p->p_type_val_to_name[avkey.target_type - + 1], + p->p_class_val_to_name[avkey.target_class - + 1], + p->p_type_val_to_name[oldtype - 1]); + return EXPAND_RULE_CONFLICT; + } + ERR(handle, + "conflicting TE rule for (%s, %s:%s): old was %s, new is %s", + p->p_type_val_to_name[avkey.source_type - 1], + p->p_type_val_to_name[avkey.target_type - 1], + p->p_class_val_to_name[avkey.target_class - 1], + p->p_type_val_to_name[oldtype - 1], + p->p_type_val_to_name[remapped_data - 1]); + return EXPAND_RULE_CONFLICT; + } + + node = find_avtab_node(handle, avtab, &avkey, cond, NULL); + if (!node) + return -1; + if (enabled) { + node->key.specified |= AVTAB_ENABLED; + } else { + node->key.specified &= ~AVTAB_ENABLED; + } + + avdatump = &node->datum; + avdatump->data = remapped_data; + + cur = cur->next; + } + + return EXPAND_RULE_SUCCESS; +} + +/* 0 for success -1 indicates failure */ +static int allocate_xperms(sepol_handle_t * handle, avtab_datum_t * avdatump, + av_extended_perms_t * extended_perms) +{ + unsigned int i; + + avtab_extended_perms_t *xperms = avdatump->xperms; + if (!xperms) { + xperms = (avtab_extended_perms_t *) + calloc(1, sizeof(avtab_extended_perms_t)); + if (!xperms) { + ERR(handle, "Out of memory!"); + return -1; + } + avdatump->xperms = xperms; + } + + switch (extended_perms->specified) { + case AVRULE_XPERMS_IOCTLFUNCTION: + xperms->specified = AVTAB_XPERMS_IOCTLFUNCTION; + break; + case AVRULE_XPERMS_IOCTLDRIVER: + xperms->specified = AVTAB_XPERMS_IOCTLDRIVER; + break; + default: + return -1; + } + + xperms->driver = extended_perms->driver; + for (i = 0; i < ARRAY_SIZE(xperms->perms); i++) + xperms->perms[i] |= extended_perms->perms[i]; + + return 0; +} + +static int expand_avrule_helper(sepol_handle_t * handle, + uint32_t specified, + cond_av_list_t ** cond, + uint32_t stype, uint32_t ttype, + class_perm_node_t * perms, avtab_t * avtab, + int enabled, av_extended_perms_t *extended_perms) +{ + avtab_key_t avkey; + avtab_datum_t *avdatump; + avtab_ptr_t node; + class_perm_node_t *cur; + + /* bail early if dontaudit's are disabled and it's a dontaudit rule */ + if ((specified & (AVRULE_DONTAUDIT|AVRULE_XPERMS_DONTAUDIT)) + && handle && handle->disable_dontaudit) + return EXPAND_RULE_SUCCESS; + + avkey.source_type = stype + 1; + avkey.target_type = ttype + 1; + avkey.specified = avrule_to_avtab_spec(specified); + + cur = perms; + while (cur) { + avkey.target_class = cur->tclass; + + node = find_avtab_node(handle, avtab, &avkey, cond, extended_perms); + if (!node) + return EXPAND_RULE_ERROR; + if (enabled) { + node->key.specified |= AVTAB_ENABLED; + } else { + node->key.specified &= ~AVTAB_ENABLED; + } + + avdatump = &node->datum; + switch (specified) { + case AVRULE_ALLOWED: + case AVRULE_AUDITALLOW: + case AVRULE_NEVERALLOW: + avdatump->data |= cur->data; + break; + case AVRULE_DONTAUDIT: + avdatump->data &= ~cur->data; + break; + case AVRULE_AUDITDENY: + /* Since a '0' in an auditdeny mask represents + * a permission we do NOT want to audit + * (dontaudit), we use the '&' operand to + * ensure that all '0's in the mask are + * retained (much unlike the allow and + * auditallow cases). + */ + avdatump->data &= cur->data; + break; + case AVRULE_XPERMS_ALLOWED: + case AVRULE_XPERMS_AUDITALLOW: + case AVRULE_XPERMS_DONTAUDIT: + case AVRULE_XPERMS_NEVERALLOW: + if (allocate_xperms(handle, avdatump, extended_perms)) + return EXPAND_RULE_ERROR; + break; + default: + ERR(handle, "Unknown specification: %"PRIu32, specified); + return EXPAND_RULE_ERROR; + } + + cur = cur->next; + } + return EXPAND_RULE_SUCCESS; +} + +static int expand_rule_helper(sepol_handle_t * handle, + policydb_t * p, uint32_t * typemap, + avrule_t * source_rule, avtab_t * dest_avtab, + cond_av_list_t ** cond, cond_av_list_t ** other, + int enabled, + ebitmap_t * stypes, ebitmap_t * ttypes) +{ + unsigned int i, j; + int retval; + ebitmap_node_t *snode, *tnode; + + ebitmap_for_each_positive_bit(stypes, snode, i) { + if (source_rule->flags & RULE_SELF) { + if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) { + retval = expand_avrule_helper(handle, source_rule->specified, + cond, i, i, source_rule->perms, + dest_avtab, enabled, source_rule->xperms); + if (retval != EXPAND_RULE_SUCCESS) + return retval; + } else { + retval = expand_terule_helper(handle, p, typemap, + source_rule->specified, cond, + other, i, i, source_rule->perms, + dest_avtab, enabled); + if (retval != EXPAND_RULE_SUCCESS) + return retval; + } + } + ebitmap_for_each_positive_bit(ttypes, tnode, j) { + if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) { + retval = expand_avrule_helper(handle, source_rule->specified, + cond, i, j, source_rule->perms, + dest_avtab, enabled, source_rule->xperms); + if (retval != EXPAND_RULE_SUCCESS) + return retval; + } else { + retval = expand_terule_helper(handle, p, typemap, + source_rule->specified, cond, + other, i, j, source_rule->perms, + dest_avtab, enabled); + if (retval != EXPAND_RULE_SUCCESS) + return retval; + } + } + } + + return EXPAND_RULE_SUCCESS; +} + +/* + * Expand a rule into a given avtab - checking for conflicting type + * rules in the destination policy. Return EXPAND_RULE_SUCCESS on + * success, EXPAND_RULE_CONFLICT if the rule conflicts with something + * (and hence was not added), or EXPAND_RULE_ERROR on error. + */ +static int convert_and_expand_rule(sepol_handle_t * handle, + policydb_t * dest_pol, uint32_t * typemap, + avrule_t * source_rule, avtab_t * dest_avtab, + cond_av_list_t ** cond, + cond_av_list_t ** other, int enabled, + int do_neverallow) +{ + int retval; + ebitmap_t stypes, ttypes; + unsigned char alwaysexpand; + + if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW) + return EXPAND_RULE_SUCCESS; + if (!do_neverallow && source_rule->specified & AVRULE_XPERMS_NEVERALLOW) + return EXPAND_RULE_SUCCESS; + + ebitmap_init(&stypes); + ebitmap_init(&ttypes); + + /* Force expansion for type rules and for self rules. */ + alwaysexpand = ((source_rule->specified & AVRULE_TYPE) || + (source_rule->flags & RULE_SELF)); + + if (expand_convert_type_set + (dest_pol, typemap, &source_rule->stypes, &stypes, alwaysexpand)) + return EXPAND_RULE_ERROR; + if (expand_convert_type_set + (dest_pol, typemap, &source_rule->ttypes, &ttypes, alwaysexpand)) + return EXPAND_RULE_ERROR; + + retval = expand_rule_helper(handle, dest_pol, typemap, + source_rule, dest_avtab, + cond, other, enabled, &stypes, &ttypes); + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&ttypes); + return retval; +} + +static int cond_avrule_list_copy(policydb_t * dest_pol, avrule_t * source_rules, + avtab_t * dest_avtab, cond_av_list_t ** list, + cond_av_list_t ** other, uint32_t * typemap, + int enabled, expand_state_t * state) +{ + avrule_t *cur; + + cur = source_rules; + while (cur) { + if (convert_and_expand_rule(state->handle, dest_pol, + typemap, cur, dest_avtab, + list, other, enabled, + 0) != EXPAND_RULE_SUCCESS) { + return -1; + } + + cur = cur->next; + } + + return 0; +} + +static int cond_node_map_bools(expand_state_t * state, cond_node_t * cn) +{ + cond_expr_t *cur; + unsigned int i; + + cur = cn->expr; + while (cur) { + if (cur->bool) + cur->bool = state->boolmap[cur->bool - 1]; + cur = cur->next; + } + + for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++) + cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1]; + + if (cond_normalize_expr(state->out, cn)) { + ERR(state->handle, "Error while normalizing conditional"); + return -1; + } + + return 0; +} + +/* copy the nodes in *reverse* order -- the result is that the last + * given conditional appears first in the policy, so as to match the + * behavior of the upstream compiler */ +static int cond_node_copy(expand_state_t * state, cond_node_t * cn) +{ + cond_node_t *new_cond, *tmp; + + if (cn == NULL) { + return 0; + } + if (cond_node_copy(state, cn->next)) { + return -1; + } + + /* If current cond_node_t is of tunable, its effective branch + * has been appended to its home decl->avrules list during link + * and now we should just skip it. */ + if (cn->flags & COND_NODE_FLAGS_TUNABLE) + return 0; + + if (cond_normalize_expr(state->base, cn)) { + ERR(state->handle, "Error while normalizing conditional"); + return -1; + } + + /* create a new temporary conditional node with the booleans + * mapped */ + tmp = cond_node_create(state->base, cn); + if (!tmp) { + ERR(state->handle, "Out of memory"); + return -1; + } + + if (cond_node_map_bools(state, tmp)) { + cond_node_destroy(tmp); + free(tmp); + ERR(state->handle, "Error mapping booleans"); + return -1; + } + + new_cond = cond_node_search(state->out, state->out->cond_list, tmp); + if (!new_cond) { + cond_node_destroy(tmp); + free(tmp); + ERR(state->handle, "Out of memory!"); + return -1; + } + cond_node_destroy(tmp); + free(tmp); + + if (cond_avrule_list_copy + (state->out, cn->avtrue_list, &state->out->te_cond_avtab, + &new_cond->true_list, &new_cond->false_list, state->typemap, + new_cond->cur_state, state)) + return -1; + if (cond_avrule_list_copy + (state->out, cn->avfalse_list, &state->out->te_cond_avtab, + &new_cond->false_list, &new_cond->true_list, state->typemap, + !new_cond->cur_state, state)) + return -1; + + return 0; +} + +static int context_copy(context_struct_t * dst, context_struct_t * src, + expand_state_t * state) +{ + dst->user = state->usermap[src->user - 1]; + dst->role = state->rolemap[src->role - 1]; + dst->type = state->typemap[src->type - 1]; + return mls_context_cpy(dst, src); +} + +static int ocontext_copy_xen(expand_state_t *state) +{ + unsigned int i; + ocontext_t *c, *n, *l; + + for (i = 0; i < OCON_NUM; i++) { + l = NULL; + for (c = state->base->ocontexts[i]; c; c = c->next) { + if (i == OCON_XEN_ISID && !c->context[0].user) { + INFO(state->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } + n = malloc(sizeof(ocontext_t)); + if (!n) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(n, 0, sizeof(ocontext_t)); + if (l) + l->next = n; + else + state->out->ocontexts[i] = n; + l = n; + switch (i) { + case OCON_XEN_ISID: + n->sid[0] = c->sid[0]; + break; + case OCON_XEN_PIRQ: + n->u.pirq = c->u.pirq; + break; + case OCON_XEN_IOPORT: + n->u.ioport.low_ioport = c->u.ioport.low_ioport; + n->u.ioport.high_ioport = + c->u.ioport.high_ioport; + break; + case OCON_XEN_IOMEM: + n->u.iomem.low_iomem = c->u.iomem.low_iomem; + n->u.iomem.high_iomem = c->u.iomem.high_iomem; + break; + case OCON_XEN_PCIDEVICE: + n->u.device = c->u.device; + break; + case OCON_XEN_DEVICETREE: + n->u.name = strdup(c->u.name); + if (!n->u.name) { + ERR(state->handle, "Out of memory!"); + return -1; + } + break; + default: + /* shouldn't get here */ + ERR(state->handle, "Unknown ocontext"); + return -1; + } + if (context_copy(&n->context[0], &c->context[0], + state)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + } + } + return 0; +} + +static int ocontext_copy_selinux(expand_state_t *state) +{ + unsigned int i, j; + ocontext_t *c, *n, *l; + + for (i = 0; i < OCON_NUM; i++) { + l = NULL; + for (c = state->base->ocontexts[i]; c; c = c->next) { + if (i == OCON_ISID && !c->context[0].user) { + INFO(state->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } + n = malloc(sizeof(ocontext_t)); + if (!n) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(n, 0, sizeof(ocontext_t)); + if (l) + l->next = n; + else + state->out->ocontexts[i] = n; + l = n; + switch (i) { + case OCON_ISID: + n->sid[0] = c->sid[0]; + break; + case OCON_FS: /* FALLTHROUGH */ + case OCON_NETIF: + n->u.name = strdup(c->u.name); + if (!n->u.name) { + ERR(state->handle, "Out of memory!"); + return -1; + } + if (context_copy + (&n->context[1], &c->context[1], state)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + break; + case OCON_IBPKEY: + n->u.ibpkey.subnet_prefix = c->u.ibpkey.subnet_prefix; + + n->u.ibpkey.low_pkey = c->u.ibpkey.low_pkey; + n->u.ibpkey.high_pkey = c->u.ibpkey.high_pkey; + break; + case OCON_IBENDPORT: + n->u.ibendport.dev_name = strdup(c->u.ibendport.dev_name); + if (!n->u.ibendport.dev_name) { + ERR(state->handle, "Out of memory!"); + return -1; + } + n->u.ibendport.port = c->u.ibendport.port; + break; + case OCON_PORT: + n->u.port.protocol = c->u.port.protocol; + n->u.port.low_port = c->u.port.low_port; + n->u.port.high_port = c->u.port.high_port; + break; + case OCON_NODE: + n->u.node.addr = c->u.node.addr; + n->u.node.mask = c->u.node.mask; + break; + case OCON_FSUSE: + n->v.behavior = c->v.behavior; + n->u.name = strdup(c->u.name); + if (!n->u.name) { + ERR(state->handle, "Out of memory!"); + return -1; + } + break; + case OCON_NODE6: + for (j = 0; j < 4; j++) + n->u.node6.addr[j] = c->u.node6.addr[j]; + for (j = 0; j < 4; j++) + n->u.node6.mask[j] = c->u.node6.mask[j]; + break; + default: + /* shouldn't get here */ + ERR(state->handle, "Unknown ocontext"); + return -1; + } + if (context_copy(&n->context[0], &c->context[0], state)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + } + } + return 0; +} + +static int ocontext_copy(expand_state_t *state, uint32_t target) +{ + int rc = -1; + switch (target) { + case SEPOL_TARGET_SELINUX: + rc = ocontext_copy_selinux(state); + break; + case SEPOL_TARGET_XEN: + rc = ocontext_copy_xen(state); + break; + default: + ERR(state->handle, "Unknown target"); + return -1; + } + return rc; +} + +static int genfs_copy(expand_state_t * state) +{ + ocontext_t *c, *newc, *l; + genfs_t *genfs, *newgenfs, *end; + + end = NULL; + for (genfs = state->base->genfs; genfs; genfs = genfs->next) { + newgenfs = malloc(sizeof(genfs_t)); + if (!newgenfs) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(newgenfs, 0, sizeof(genfs_t)); + newgenfs->fstype = strdup(genfs->fstype); + if (!newgenfs->fstype) { + free(newgenfs); + ERR(state->handle, "Out of memory!"); + return -1; + } + if (!end) + state->out->genfs = newgenfs; + else + end->next = newgenfs; + end = newgenfs; + + l = NULL; + for (c = genfs->head; c; c = c->next) { + newc = malloc(sizeof(ocontext_t)); + if (!newc) { + ERR(state->handle, "Out of memory!"); + return -1; + } + memset(newc, 0, sizeof(ocontext_t)); + newc->u.name = strdup(c->u.name); + if (!newc->u.name) { + ERR(state->handle, "Out of memory!"); + free(newc); + return -1; + } + newc->v.sclass = c->v.sclass; + context_copy(&newc->context[0], &c->context[0], state); + if (l) + l->next = newc; + else + newgenfs->head = newc; + l = newc; + } + } + return 0; +} + +static int type_attr_map(hashtab_key_t key + __attribute__ ((unused)), hashtab_datum_t datum, + void *ptr) +{ + type_datum_t *type; + expand_state_t *state = ptr; + policydb_t *p = state->out; + unsigned int i; + ebitmap_node_t *tnode; + int value; + + type = (type_datum_t *) datum; + value = type->s.value; + + if (type->flavor == TYPE_ATTRIB) { + if (!(type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE)) { + if (ksu_ebitmap_cpy(&p->attr_type_map[value - 1], &type->types)) { + goto oom; + } + ebitmap_for_each_positive_bit(&type->types, tnode, i) { + if (ksu_ebitmap_set_bit(&p->type_attr_map[i], value - 1, 1)) { + goto oom; + } + } + } else { + /* Attribute is being expanded, so remove */ + if (ksu_ebitmap_set_bit(&p->type_attr_map[value - 1], value - 1, 0)) { + goto oom; + } + } + } else { + if (ksu_ebitmap_set_bit(&p->attr_type_map[value - 1], value - 1, 1)) { + goto oom; + } + } + + return 0; + +oom: + ERR(state->handle, "Out of memory!"); + return -1; +} + +/* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy. + * this should not be called until after all the blocks have been processed and the attributes in target policy + * are complete. */ +int expand_convert_type_set(policydb_t * p, uint32_t * typemap, + type_set_t * set, ebitmap_t * types, + unsigned char alwaysexpand) +{ + type_set_t tmpset; + + type_set_init(&tmpset); + + if (map_ebitmap(&set->types, &tmpset.types, typemap)) + return -1; + + if (map_ebitmap(&set->negset, &tmpset.negset, typemap)) + return -1; + + tmpset.flags = set->flags; + + if (type_set_expand(&tmpset, types, p, alwaysexpand)) + return -1; + + type_set_destroy(&tmpset); + + return 0; +} + +/* Expand a rule into a given avtab - checking for conflicting type + * rules. Return 1 on success, 0 if the rule conflicts with something + * (and hence was not added), or -1 on error. */ +int expand_rule(sepol_handle_t * handle, + policydb_t * source_pol, + avrule_t * source_rule, avtab_t * dest_avtab, + cond_av_list_t ** cond, cond_av_list_t ** other, int enabled) +{ + int retval; + ebitmap_t stypes, ttypes; + + if ((source_rule->specified & AVRULE_NEVERALLOW) + || (source_rule->specified & AVRULE_XPERMS_NEVERALLOW)) + return 1; + + ebitmap_init(&stypes); + ebitmap_init(&ttypes); + + if (type_set_expand(&source_rule->stypes, &stypes, source_pol, 1)) + return -1; + if (type_set_expand(&source_rule->ttypes, &ttypes, source_pol, 1)) + return -1; + retval = expand_rule_helper(handle, source_pol, NULL, + source_rule, dest_avtab, + cond, other, enabled, &stypes, &ttypes); + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&ttypes); + return retval; +} + +/* Expand a role set into an ebitmap containing the roles. + * This handles the attribute and flags. + * Attribute expansion depends on if the rolemap is available. + * During module compile the rolemap is not available, the + * possible duplicates of a regular role and the role attribute + * the regular role belongs to could be properly handled by + * copy_role_trans and copy_role_allow. + */ +int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap) +{ + unsigned int i; + ebitmap_node_t *rnode; + ebitmap_t mapped_roles, roles; + policydb_t *p = out; + role_datum_t *role; + + ebitmap_init(r); + + if (x->flags & ROLE_STAR) { + for (i = 0; i < p->p_roles.nprim; i++) + if (ksu_ebitmap_set_bit(r, i, 1)) + return -1; + return 0; + } + + ebitmap_init(&mapped_roles); + ebitmap_init(&roles); + + if (rolemap) { + assert(base != NULL); + ebitmap_for_each_positive_bit(&x->roles, rnode, i) { + /* take advantage of p_role_val_to_struct[] + * of the base module */ + role = base->role_val_to_struct[i]; + assert(role != NULL); + if (role->flavor == ROLE_ATTRIB) { + if (ebitmap_union(&roles, + &role->roles)) + goto bad; + } else { + if (ksu_ebitmap_set_bit(&roles, i, 1)) + goto bad; + } + } + if (map_ebitmap(&roles, &mapped_roles, rolemap)) + goto bad; + } else { + if (ksu_ebitmap_cpy(&mapped_roles, &x->roles)) + goto bad; + } + + ebitmap_for_each_positive_bit(&mapped_roles, rnode, i) { + if (ksu_ebitmap_set_bit(r, i, 1)) + goto bad; + } + + ksu_ebitmap_destroy(&mapped_roles); + ksu_ebitmap_destroy(&roles); + + /* if role is to be complimented, invert the entire bitmap here */ + if (x->flags & ROLE_COMP) { + for (i = 0; i < p->p_roles.nprim; i++) { + if (ksu_ebitmap_get_bit(r, i)) { + if (ksu_ebitmap_set_bit(r, i, 0)) + return -1; + } else { + if (ksu_ebitmap_set_bit(r, i, 1)) + return -1; + } + } + } + return 0; + +bad: + ksu_ebitmap_destroy(&mapped_roles); + ksu_ebitmap_destroy(&roles); + return -1; +} + +/* Expand a type set into an ebitmap containing the types. This + * handles the negset, attributes, and flags. + * Attribute expansion depends on several factors: + * - if alwaysexpand is 1, then they will be expanded, + * - if the type set has a negset or flags, then they will be expanded, + * - otherwise, they will not be expanded. + */ +int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + unsigned char alwaysexpand) +{ + unsigned int i; + ebitmap_t types, neg_types; + ebitmap_node_t *tnode; + unsigned char expand = alwaysexpand || !ebitmap_is_empty(&set->negset) || set->flags; + type_datum_t *type; + int rc =-1; + + ebitmap_init(&types); + ebitmap_init(t); + + /* First go through the types and OR all the attributes to types */ + ebitmap_for_each_positive_bit(&set->types, tnode, i) { + /* + * invalid policies might have more types set in the ebitmap than + * what's available in the type_val_to_struct mapping + */ + if (i >= p->p_types.nprim) + goto err_types; + + type = p->type_val_to_struct[i]; + + if (!type) { + goto err_types; + } + + if (type->flavor == TYPE_ATTRIB && + (expand || (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE))) { + if (ebitmap_union(&types, &type->types)) { + goto err_types; + } + } else { + if (ksu_ebitmap_set_bit(&types, i, 1)) { + goto err_types; + } + } + } + + /* Now do the same thing for negset */ + ebitmap_init(&neg_types); + ebitmap_for_each_positive_bit(&set->negset, tnode, i) { + if (p->type_val_to_struct[i] && + p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { + if (ebitmap_union + (&neg_types, + &p->type_val_to_struct[i]->types)) { + goto err_neg; + } + } else { + if (ksu_ebitmap_set_bit(&neg_types, i, 1)) { + goto err_neg; + } + } + } + + if (set->flags & TYPE_STAR) { + /* set all types not in neg_types */ + for (i = 0; i < p->p_types.nprim; i++) { + if (ksu_ebitmap_get_bit(&neg_types, i)) + continue; + if (p->type_val_to_struct[i] && + p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) + continue; + if (ksu_ebitmap_set_bit(t, i, 1)) + goto err_neg; + } + goto out; + } + + ebitmap_for_each_positive_bit(&types, tnode, i) { + if (!ksu_ebitmap_get_bit(&neg_types, i)) + if (ksu_ebitmap_set_bit(t, i, 1)) + goto err_neg; + } + + if (set->flags & TYPE_COMP) { + for (i = 0; i < p->p_types.nprim; i++) { + if (p->type_val_to_struct[i] && + p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { + assert(!ksu_ebitmap_get_bit(t, i)); + continue; + } + if (ksu_ebitmap_get_bit(t, i)) { + if (ksu_ebitmap_set_bit(t, i, 0)) + goto err_neg; + } else { + if (ksu_ebitmap_set_bit(t, i, 1)) + goto err_neg; + } + } + } + + out: + rc = 0; + + err_neg: + ksu_ebitmap_destroy(&neg_types); + err_types: + ksu_ebitmap_destroy(&types); + + return rc; +} + +static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap, + avrule_t * source_rule) +{ + ebitmap_t stypes, ttypes; + avrule_t *avrule; + class_perm_node_t *cur_perm, *new_perm, *tail_perm; + av_extended_perms_t *xperms = NULL; + + ebitmap_init(&stypes); + ebitmap_init(&ttypes); + + if (expand_convert_type_set + (dest_pol, typemap, &source_rule->stypes, &stypes, 1)) + return -1; + if (expand_convert_type_set + (dest_pol, typemap, &source_rule->ttypes, &ttypes, 1)) + return -1; + + avrule = (avrule_t *) malloc(sizeof(avrule_t)); + if (!avrule) + return -1; + + avrule_init(avrule); + avrule->specified = source_rule->specified; + avrule->line = source_rule->line; + avrule->flags = source_rule->flags; + avrule->source_line = source_rule->source_line; + if (source_rule->source_filename) { + avrule->source_filename = strdup(source_rule->source_filename); + if (!avrule->source_filename) + goto err; + } + + if (ksu_ebitmap_cpy(&avrule->stypes.types, &stypes)) + goto err; + + if (ksu_ebitmap_cpy(&avrule->ttypes.types, &ttypes)) + goto err; + + cur_perm = source_rule->perms; + tail_perm = NULL; + while (cur_perm) { + new_perm = + (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); + if (!new_perm) + goto err; + class_perm_node_init(new_perm); + new_perm->tclass = cur_perm->tclass; + assert(new_perm->tclass); + + /* once we have modules with permissions we'll need to map the permissions (and classes) */ + new_perm->data = cur_perm->data; + + if (!avrule->perms) + avrule->perms = new_perm; + + if (tail_perm) + tail_perm->next = new_perm; + tail_perm = new_perm; + cur_perm = cur_perm->next; + } + + /* copy over extended permissions */ + if (source_rule->xperms) { + xperms = calloc(1, sizeof(av_extended_perms_t)); + if (!xperms) + goto err; + memcpy(xperms, source_rule->xperms, sizeof(av_extended_perms_t)); + avrule->xperms = xperms; + } + + /* just prepend the avrule to the first branch; it'll never be + written to disk */ + if (!dest_pol->global->branch_list->avrules) + dest_pol->global->branch_list->avrules = avrule; + else { + avrule->next = dest_pol->global->branch_list->avrules; + dest_pol->global->branch_list->avrules = avrule; + } + + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&ttypes); + + return 0; + + err: + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&ttypes); + ksu_ebitmap_destroy(&avrule->stypes.types); + ksu_ebitmap_destroy(&avrule->ttypes.types); + cur_perm = avrule->perms; + while (cur_perm) { + tail_perm = cur_perm->next; + free(cur_perm); + cur_perm = tail_perm; + } + free(xperms); + free(avrule); + return -1; +} + +/* + * Expands the avrule blocks for a policy. RBAC rules are copied. Neverallow + * rules are copied or expanded as per the settings in the state object; all + * other AV rules are expanded. If neverallow rules are expanded, they are not + * copied, otherwise they are copied for later use by the assertion checker. + */ +static int copy_and_expand_avrule_block(expand_state_t * state) +{ + avrule_block_t *curblock = state->base->global; + avrule_block_t *prevblock; + int retval = -1; + + if (ksu_avtab_alloc(&state->out->te_avtab, MAX_AVTAB_SIZE)) { + ERR(state->handle, "Out of Memory!"); + return -1; + } + + if (ksu_avtab_alloc(&state->out->te_cond_avtab, MAX_AVTAB_SIZE)) { + ERR(state->handle, "Out of Memory!"); + return -1; + } + + while (curblock) { + avrule_decl_t *decl = curblock->enabled; + avrule_t *cur_avrule; + + if (decl == NULL) { + /* nothing was enabled within this block */ + goto cont; + } + + /* copy role allows and role trans */ + if (copy_role_allows(state, decl->role_allow_rules) != 0 || + copy_role_trans(state, decl->role_tr_rules) != 0) { + goto cleanup; + } + + if (expand_filename_trans(state, decl->filename_trans_rules)) + goto cleanup; + + /* expand the range transition rules */ + if (expand_range_trans(state, decl->range_tr_rules)) + goto cleanup; + + /* copy rules */ + cur_avrule = decl->avrules; + while (cur_avrule != NULL) { + if (!(state->expand_neverallow) + && cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)) { + /* copy this over directly so that assertions are checked later */ + if (copy_neverallow + (state->out, state->typemap, cur_avrule)) + ERR(state->handle, + "Error while copying neverallow."); + } else { + if (cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)) + state->out->unsupported_format = 1; + if (convert_and_expand_rule + (state->handle, state->out, state->typemap, + cur_avrule, &state->out->te_avtab, NULL, + NULL, 0, + state->expand_neverallow) != + EXPAND_RULE_SUCCESS) { + goto cleanup; + } + } + cur_avrule = cur_avrule->next; + } + + /* copy conditional rules */ + if (cond_node_copy(state, decl->cond_list)) + goto cleanup; + + cont: + prevblock = curblock; + curblock = curblock->next; + + if (state->handle && state->handle->expand_consume_base) { + /* set base top avrule block in case there + * is an error condition and the policy needs + * to be destroyed */ + state->base->global = curblock; + avrule_block_destroy(prevblock); + } + } + + retval = 0; + + cleanup: + return retval; +} + +/* + * This function allows external users of the library (such as setools) to + * expand only the avrules and optionally perform expansion of neverallow rules + * or expand into the same policy for analysis purposes. + */ +int expand_module_avrules(sepol_handle_t * handle, policydb_t * base, + policydb_t * out, uint32_t * typemap, + uint32_t * boolmap, uint32_t * rolemap, + uint32_t * usermap, int verbose, + int expand_neverallow) +{ + expand_state_t state; + + expand_state_init(&state); + + state.base = base; + state.out = out; + state.typemap = typemap; + state.boolmap = boolmap; + state.rolemap = rolemap; + state.usermap = usermap; + state.handle = handle; + state.verbose = verbose; + state.expand_neverallow = expand_neverallow; + + return copy_and_expand_avrule_block(&state); +} + +static void discard_tunables(sepol_handle_t *sh, policydb_t *pol) +{ + avrule_block_t *block; + avrule_decl_t *decl; + cond_node_t *cur_node; + cond_expr_t *cur_expr; + int cur_state, preserve_tunables = 0; + avrule_t *tail, *to_be_appended; + + if (sh && sh->preserve_tunables) + preserve_tunables = 1; + + /* Iterate through all cond_node of all enabled decls, if a cond_node + * is about tunable, calculate its state value and concatenate one of + * its avrule list to the current decl->avrules list. On the other + * hand, the disabled unused branch of a tunable would be discarded. + * + * Note, such tunable cond_node would be skipped over in expansion, + * so we won't have to worry about removing it from decl->cond_list + * here :-) + * + * If tunables are requested to be preserved then they would be + * "transformed" as booleans by having their TUNABLE flag cleared. + */ + for (block = pol->global; block != NULL; block = block->next) { + decl = block->enabled; + if (decl == NULL || decl->enabled == 0) + continue; + + tail = decl->avrules; + while (tail && tail->next) + tail = tail->next; + + for (cur_node = decl->cond_list; cur_node != NULL; + cur_node = cur_node->next) { + int booleans, tunables, i; + cond_bool_datum_t *booldatum; + cond_bool_datum_t *tmp[COND_EXPR_MAXDEPTH]; + + booleans = tunables = 0; + memset(tmp, 0, sizeof(cond_bool_datum_t *) * COND_EXPR_MAXDEPTH); + + for (cur_expr = cur_node->expr; cur_expr != NULL; + cur_expr = cur_expr->next) { + if (cur_expr->expr_type != COND_BOOL) + continue; + booldatum = pol->bool_val_to_struct[cur_expr->bool - 1]; + if (booldatum->flags & COND_BOOL_FLAGS_TUNABLE) + tmp[tunables++] = booldatum; + else + booleans++; + } + + /* bool_copy_callback() at link phase has ensured + * that no mixture of tunables and booleans in one + * expression. However, this would be broken by the + * request to preserve tunables */ + if (!preserve_tunables) + assert(!(booleans && tunables)); + + if (booleans || preserve_tunables) { + cur_node->flags &= ~COND_NODE_FLAGS_TUNABLE; + if (tunables) { + for (i = 0; i < tunables; i++) + tmp[i]->flags &= ~COND_BOOL_FLAGS_TUNABLE; + } + } else { + cur_node->flags |= COND_NODE_FLAGS_TUNABLE; + cur_state = cond_evaluate_expr(pol, cur_node->expr); + if (cur_state == -1) { + printf("Expression result was " + "undefined, skipping all" + "rules\n"); + continue; + } + + to_be_appended = (cur_state == 1) ? + cur_node->avtrue_list : cur_node->avfalse_list; + + if (tail) + tail->next = to_be_appended; + else + tail = decl->avrules = to_be_appended; + + /* Now that the effective branch has been + * appended, neutralize its original pointer */ + if (cur_state == 1) + cur_node->avtrue_list = NULL; + else + cur_node->avfalse_list = NULL; + + /* Update the tail of decl->avrules for + * further concatenation */ + while (tail && tail->next) + tail = tail->next; + } + } + } +} + +/* Linking should always be done before calling expand, even if + * there is only a base since all optionals are dealt with at link time + * the base passed in should be indexed and avrule blocks should be + * enabled. + */ +int expand_module(sepol_handle_t * handle, + policydb_t * base, policydb_t * out, int verbose, int check) +{ + int retval = -1; + unsigned int i; + expand_state_t state; + avrule_block_t *curblock; + + /* Append tunable's avtrue_list or avfalse_list to the avrules list + * of its home decl depending on its state value, so that the effect + * rules of a tunable would be added to te_avtab permanently. Whereas + * the disabled unused branch would be discarded. + * + * Originally this function is called at the very end of link phase, + * however, we need to keep the linked policy intact for analysis + * purpose. */ + discard_tunables(handle, base); + + expand_state_init(&state); + + state.verbose = verbose; + state.typemap = NULL; + state.base = base; + state.out = out; + state.handle = handle; + + if (base->policy_type != POLICY_BASE) { + ERR(handle, "Target of expand was not a base policy."); + return -1; + } + + state.out->policy_type = POLICY_KERN; + state.out->policyvers = POLICYDB_VERSION_MAX; + if (state.base->name) { + state.out->name = strdup(state.base->name); + } + + /* Copy mls state from base to out */ + out->mls = base->mls; + out->handle_unknown = base->handle_unknown; + + /* Copy target from base to out */ + out->target_platform = base->target_platform; + + /* Copy policy capabilities */ + if (ksu_ebitmap_cpy(&out->policycaps, &base->policycaps)) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + + if ((state.typemap = + (uint32_t *) calloc(state.base->p_types.nprim, + sizeof(uint32_t))) == NULL) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + + state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t)); + if (!state.boolmap) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + + state.rolemap = (uint32_t *)calloc(state.base->p_roles.nprim, sizeof(uint32_t)); + if (!state.rolemap) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + + state.usermap = (uint32_t *)calloc(state.base->p_users.nprim, sizeof(uint32_t)); + if (!state.usermap) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + + /* order is important - types must be first */ + + /* copy types */ + if (ksu_hashtab_map(state.base->p_types.table, type_copy_callback, &state)) { + goto cleanup; + } + + /* convert attribute type sets */ + if (ksu_hashtab_map + (state.base->p_types.table, attr_convert_callback, &state)) { + goto cleanup; + } + + /* copy commons */ + if (ksu_hashtab_map + (state.base->p_commons.table, common_copy_callback, &state)) { + goto cleanup; + } + + /* copy classes, note, this does not copy constraints, constraints can't be + * copied until after all the blocks have been processed and attributes are complete */ + if (ksu_hashtab_map + (state.base->p_classes.table, class_copy_callback, &state)) { + goto cleanup; + } + + /* copy type bounds */ + if (ksu_hashtab_map(state.base->p_types.table, + type_bounds_copy_callback, &state)) + goto cleanup; + + /* copy aliases */ + if (ksu_hashtab_map(state.base->p_types.table, alias_copy_callback, &state)) + goto cleanup; + + /* index here so that type indexes are available for role_copy_callback */ + if (policydb_index_others(handle, out, verbose)) { + ERR(handle, "Error while indexing out symbols"); + goto cleanup; + } + + /* copy roles */ + if (ksu_hashtab_map(state.base->p_roles.table, role_copy_callback, &state)) + goto cleanup; + if (ksu_hashtab_map(state.base->p_roles.table, + role_bounds_copy_callback, &state)) + goto cleanup; + + /* copy MLS's sensitivity level and categories - this needs to be done + * before expanding users (they need to be indexed too) */ + if (ksu_hashtab_map(state.base->p_levels.table, sens_copy_callback, &state)) + goto cleanup; + if (ksu_hashtab_map(state.base->p_cats.table, cats_copy_callback, &state)) + goto cleanup; + if (policydb_index_others(handle, out, verbose)) { + ERR(handle, "Error while indexing out symbols"); + goto cleanup; + } + + /* copy users */ + if (ksu_hashtab_map(state.base->p_users.table, user_copy_callback, &state)) + goto cleanup; + if (ksu_hashtab_map(state.base->p_users.table, + user_bounds_copy_callback, &state)) + goto cleanup; + + /* copy bools */ + if (ksu_hashtab_map(state.base->p_bools.table, bool_copy_callback, &state)) + goto cleanup; + + if (policydb_index_classes(out)) { + ERR(handle, "Error while indexing out classes"); + goto cleanup; + } + if (policydb_index_others(handle, out, verbose)) { + ERR(handle, "Error while indexing out symbols"); + goto cleanup; + } + + /* loop through all decls and union attributes, roles, users */ + for (curblock = state.base->global; curblock != NULL; + curblock = curblock->next) { + avrule_decl_t *decl = curblock->enabled; + + if (decl == NULL) { + /* nothing was enabled within this block */ + continue; + } + + /* convert attribute type sets */ + if (ksu_hashtab_map + (decl->p_types.table, attr_convert_callback, &state)) { + goto cleanup; + } + + /* copy roles */ + if (ksu_hashtab_map + (decl->p_roles.table, role_copy_callback, &state)) + goto cleanup; + + /* copy users */ + if (ksu_hashtab_map + (decl->p_users.table, user_copy_callback, &state)) + goto cleanup; + + } + + /* remap role dominates bitmaps */ + if (ksu_hashtab_map(state.out->p_roles.table, role_remap_dominates, &state)) { + goto cleanup; + } + + /* escalate the type_set_t in a role attribute to all regular roles + * that belongs to it. */ + if (ksu_hashtab_map(state.base->p_roles.table, role_fix_callback, &state)) + goto cleanup; + + if (copy_and_expand_avrule_block(&state) < 0) { + ERR(handle, "Error during expand"); + goto cleanup; + } + + /* copy constraints */ + if (ksu_hashtab_map + (state.base->p_classes.table, constraint_copy_callback, &state)) { + goto cleanup; + } + + cond_optimize_lists(state.out->cond_list); + if (evaluate_conds(state.out)) + goto cleanup; + + /* copy ocontexts */ + if (ocontext_copy(&state, out->target_platform)) + goto cleanup; + + /* copy genfs */ + if (genfs_copy(&state)) + goto cleanup; + + /* Build the type<->attribute maps and remove attributes. */ + state.out->attr_type_map = calloc(state.out->p_types.nprim, + sizeof(ebitmap_t)); + state.out->type_attr_map = calloc(state.out->p_types.nprim, + sizeof(ebitmap_t)); + if (!state.out->attr_type_map || !state.out->type_attr_map) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + for (i = 0; i < state.out->p_types.nprim; i++) { + /* add the type itself as the degenerate case */ + if (ksu_ebitmap_set_bit(&state.out->type_attr_map[i], i, 1)) { + ERR(handle, "Out of memory!"); + goto cleanup; + } + } + if (ksu_hashtab_map(state.out->p_types.table, type_attr_map, &state)) + goto cleanup; + if (check) { + if (hierarchy_check_constraints(handle, state.out)) + goto cleanup; + + if (check_assertions + (handle, state.out, + state.out->global->branch_list->avrules)) + goto cleanup; + } + + retval = 0; + + cleanup: + free(state.typemap); + free(state.boolmap); + free(state.rolemap); + free(state.usermap); + return retval; +} + +static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d) +{ + avtab_ptr_t node; + avtab_datum_t *avd; + avtab_extended_perms_t *xperms; + unsigned int i; + unsigned int match = 0; + + if (k->specified & AVTAB_XPERMS) { + /* + * AVTAB_XPERMS entries are not necessarily unique. + * find node with matching xperms + */ + node = ksu_avtab_search_node(a, k); + while (node) { + if ((node->datum.xperms->specified == d->xperms->specified) && + (node->datum.xperms->driver == d->xperms->driver)) { + match = 1; + break; + } + node = ksu_avtab_search_node_next(node, k->specified); + } + if (!match) + node = NULL; + } else { + node = ksu_avtab_search_node(a, k); + } + + if (!node || ((k->specified & AVTAB_ENABLED) != + (node->key.specified & AVTAB_ENABLED))) { + node = ksu_avtab_insert_nonunique(a, k, d); + if (!node) { + ERR(NULL, "Out of memory!"); + return -1; + } + return 0; + } + + avd = &node->datum; + xperms = node->datum.xperms; + switch (k->specified & ~AVTAB_ENABLED) { + case AVTAB_ALLOWED: + case AVTAB_AUDITALLOW: + avd->data |= d->data; + break; + case AVTAB_AUDITDENY: + avd->data &= d->data; + break; + case AVTAB_XPERMS_ALLOWED: + case AVTAB_XPERMS_AUDITALLOW: + case AVTAB_XPERMS_DONTAUDIT: + for (i = 0; i < ARRAY_SIZE(xperms->perms); i++) + xperms->perms[i] |= d->xperms->perms[i]; + break; + default: + ERR(NULL, "Type conflict!"); + return -1; + } + + return 0; +} + +struct expand_avtab_data { + avtab_t *expa; + policydb_t *p; + +}; + +static int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args) +{ + struct expand_avtab_data *ptr = args; + avtab_t *expa = ptr->expa; + policydb_t *p = ptr->p; + type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; + type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; + ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; + ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; + ebitmap_node_t *snode, *tnode; + unsigned int i, j; + avtab_key_t newkey; + int rc; + + newkey.target_class = k->target_class; + newkey.specified = k->specified; + + if (stype && ttype && stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { + /* Both are individual types, no expansion required. */ + return expand_avtab_insert(expa, k, d); + } + + if (stype && stype->flavor != TYPE_ATTRIB) { + /* Source is an individual type, target is an attribute. */ + newkey.source_type = k->source_type; + ebitmap_for_each_positive_bit(tattr, tnode, j) { + newkey.target_type = j + 1; + rc = expand_avtab_insert(expa, &newkey, d); + if (rc) + return -1; + } + return 0; + } + + if (ttype && ttype->flavor != TYPE_ATTRIB) { + /* Target is an individual type, source is an attribute. */ + newkey.target_type = k->target_type; + ebitmap_for_each_positive_bit(sattr, snode, i) { + newkey.source_type = i + 1; + rc = expand_avtab_insert(expa, &newkey, d); + if (rc) + return -1; + } + return 0; + } + + /* Both source and target type are attributes. */ + ebitmap_for_each_positive_bit(sattr, snode, i) { + ebitmap_for_each_positive_bit(tattr, tnode, j) { + newkey.source_type = i + 1; + newkey.target_type = j + 1; + rc = expand_avtab_insert(expa, &newkey, d); + if (rc) + return -1; + } + } + + return 0; +} + +int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa) +{ + struct expand_avtab_data data; + + if (ksu_avtab_alloc(expa, MAX_AVTAB_SIZE)) { + ERR(NULL, "Out of memory!"); + return -1; + } + + data.expa = expa; + data.p = p; + return avtab_map(a, expand_avtab_node, &data); +} + +static int expand_cond_insert(cond_av_list_t ** l, + avtab_t * expa, + avtab_key_t * k, avtab_datum_t * d) +{ + avtab_ptr_t node; + avtab_datum_t *avd; + cond_av_list_t *nl; + + node = ksu_avtab_search_node(expa, k); + if (!node || + (k->specified & AVTAB_ENABLED) != + (node->key.specified & AVTAB_ENABLED)) { + node = ksu_avtab_insert_nonunique(expa, k, d); + if (!node) { + ERR(NULL, "Out of memory!"); + return -1; + } + node->parse_context = (void *)1; + nl = (cond_av_list_t *) malloc(sizeof(*nl)); + if (!nl) { + ERR(NULL, "Out of memory!"); + return -1; + } + memset(nl, 0, sizeof(*nl)); + nl->node = node; + nl->next = *l; + *l = nl; + return 0; + } + + avd = &node->datum; + switch (k->specified & ~AVTAB_ENABLED) { + case AVTAB_ALLOWED: + case AVTAB_AUDITALLOW: + avd->data |= d->data; + break; + case AVTAB_AUDITDENY: + avd->data &= d->data; + break; + default: + ERR(NULL, "Type conflict!"); + return -1; + } + + return 0; +} + +static int expand_cond_av_node(policydb_t * p, + avtab_ptr_t node, + cond_av_list_t ** newl, avtab_t * expa) +{ + avtab_key_t *k = &node->key; + avtab_datum_t *d = &node->datum; + type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; + type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; + ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; + ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; + ebitmap_node_t *snode, *tnode; + unsigned int i, j; + avtab_key_t newkey; + int rc; + + newkey.target_class = k->target_class; + newkey.specified = k->specified; + + if (stype && ttype && stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { + /* Both are individual types, no expansion required. */ + return expand_cond_insert(newl, expa, k, d); + } + + if (stype && stype->flavor != TYPE_ATTRIB) { + /* Source is an individual type, target is an attribute. */ + newkey.source_type = k->source_type; + ebitmap_for_each_positive_bit(tattr, tnode, j) { + newkey.target_type = j + 1; + rc = expand_cond_insert(newl, expa, &newkey, d); + if (rc) + return -1; + } + return 0; + } + + if (ttype && ttype->flavor != TYPE_ATTRIB) { + /* Target is an individual type, source is an attribute. */ + newkey.target_type = k->target_type; + ebitmap_for_each_positive_bit(sattr, snode, i) { + newkey.source_type = i + 1; + rc = expand_cond_insert(newl, expa, &newkey, d); + if (rc) + return -1; + } + return 0; + } + + /* Both source and target type are attributes. */ + ebitmap_for_each_positive_bit(sattr, snode, i) { + ebitmap_for_each_positive_bit(tattr, tnode, j) { + newkey.source_type = i + 1; + newkey.target_type = j + 1; + rc = expand_cond_insert(newl, expa, &newkey, d); + if (rc) + return -1; + } + } + + return 0; +} + +int expand_cond_av_list(policydb_t * p, cond_av_list_t * l, + cond_av_list_t ** newl, avtab_t * expa) +{ + cond_av_list_t *cur; + avtab_ptr_t node; + int rc; + + if (ksu_avtab_alloc(expa, MAX_AVTAB_SIZE)) { + ERR(NULL, "Out of memory!"); + return -1; + } + + *newl = NULL; + for (cur = l; cur; cur = cur->next) { + node = cur->node; + rc = expand_cond_av_node(p, node, newl, expa); + if (rc) + return rc; + } + + return 0; +} diff --git a/kernel/libsepol/src/expand.o b/kernel/libsepol/src/expand.o new file mode 100644 index 00000000..fb38d4d5 Binary files /dev/null and b/kernel/libsepol/src/expand.o differ diff --git a/kernel/libsepol/src/flask.h b/kernel/libsepol/src/flask.h new file mode 100644 index 00000000..b4130bbc --- /dev/null +++ b/kernel/libsepol/src/flask.h @@ -0,0 +1,38 @@ +/* This file is automatically generated. Do not edit. */ +#ifndef _SEPOL_POLICYDB_FLASK_H_ +#define _SEPOL_POLICYDB_FLASK_H_ + +/* + * Security identifier indices for initial entities + */ +#define SECINITSID_KERNEL 1 +#define SECINITSID_SECURITY 2 +#define SECINITSID_UNLABELED 3 +#define SECINITSID_FS 4 +#define SECINITSID_FILE 5 +#define SECINITSID_FILE_LABELS 6 +#define SECINITSID_INIT 7 +#define SECINITSID_ANY_SOCKET 8 +#define SECINITSID_PORT 9 +#define SECINITSID_NETIF 10 +#define SECINITSID_NETMSG 11 +#define SECINITSID_NODE 12 +#define SECINITSID_IGMP_PACKET 13 +#define SECINITSID_ICMP_SOCKET 14 +#define SECINITSID_TCP_SOCKET 15 +#define SECINITSID_SYSCTL_MODPROBE 16 +#define SECINITSID_SYSCTL 17 +#define SECINITSID_SYSCTL_FS 18 +#define SECINITSID_SYSCTL_KERNEL 19 +#define SECINITSID_SYSCTL_NET 20 +#define SECINITSID_SYSCTL_NET_UNIX 21 +#define SECINITSID_SYSCTL_VM 22 +#define SECINITSID_SYSCTL_DEV 23 +#define SECINITSID_KMOD 24 +#define SECINITSID_POLICY 25 +#define SECINITSID_SCMP_PACKET 26 +#define SECINITSID_DEVNULL 27 + +#define SECINITSID_NUM 27 + +#endif diff --git a/kernel/libsepol/src/handle.c b/kernel/libsepol/src/handle.c new file mode 100644 index 00000000..7f27dd36 --- /dev/null +++ b/kernel/libsepol/src/handle.c @@ -0,0 +1,60 @@ +// #include +// #include +#include "handle.h" +#include "debug.h" + +sepol_handle_t *sepol_handle_create(void) +{ + + sepol_handle_t *sh = malloc(sizeof(sepol_handle_t)); + if (sh == NULL) + return NULL; + + /* Set callback */ + sh->msg_callback = sepol_msg_default_handler; + sh->msg_callback_arg = NULL; + + /* by default do not disable dontaudits */ + sh->disable_dontaudit = 0; + sh->expand_consume_base = 0; + + /* by default needless unused branch of tunables would be discarded */ + sh->preserve_tunables = 0; + + return sh; +} + +int sepol_get_preserve_tunables(sepol_handle_t *sh) +{ + assert(sh != NULL); + return sh->preserve_tunables; +} + +void sepol_set_preserve_tunables(sepol_handle_t * sh, int preserve_tunables) +{ + assert(sh !=NULL); + sh->preserve_tunables = preserve_tunables; +} + +int sepol_get_disable_dontaudit(sepol_handle_t *sh) +{ + assert(sh !=NULL); + return sh->disable_dontaudit; +} + +void sepol_set_disable_dontaudit(sepol_handle_t * sh, int disable_dontaudit) +{ + assert(sh !=NULL); + sh->disable_dontaudit = disable_dontaudit; +} + +void sepol_set_expand_consume_base(sepol_handle_t *sh, int consume_base) +{ + assert(sh != NULL); + sh->expand_consume_base = consume_base; +} + +void sepol_handle_destroy(sepol_handle_t * sh) +{ + free(sh); +} diff --git a/kernel/libsepol/src/handle.h b/kernel/libsepol/src/handle.h new file mode 100644 index 00000000..7728d04b --- /dev/null +++ b/kernel/libsepol/src/handle.h @@ -0,0 +1,23 @@ +#ifndef _SEPOL_INTERNAL_HANDLE_H_ +#define _SEPOL_INTERNAL_HANDLE_H_ + +#include + +struct sepol_handle { + /* Error handling */ + int msg_level; + const char *msg_channel; + const char *msg_fname; +#ifdef __GNUC__ + __attribute__ ((format(printf, 3, 4))) +#endif + void (*msg_callback) (void *varg, + sepol_handle_t * handle, const char *fmt, ...); + void *msg_callback_arg; + + int disable_dontaudit; + int expand_consume_base; + int preserve_tunables; +}; + +#endif diff --git a/kernel/libsepol/src/handle.o b/kernel/libsepol/src/handle.o new file mode 100644 index 00000000..6e889de5 Binary files /dev/null and b/kernel/libsepol/src/handle.o differ diff --git a/kernel/libsepol/src/hashtab.c b/kernel/libsepol/src/hashtab.c new file mode 100644 index 00000000..5d78860a --- /dev/null +++ b/kernel/libsepol/src/hashtab.c @@ -0,0 +1,269 @@ + +/* Author : Stephen Smalley, */ + +/* + * Updated : Karl MacMillan + * + * Copyright (C) 2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/* FLASK */ + +/* + * Implementation of the hash table type. + */ + +// #include +#include +#include + +#include "private.h" + +hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, + const_hashtab_key_t key), + int (*keycmp) (hashtab_t h, + const_hashtab_key_t key1, + const_hashtab_key_t key2), + unsigned int size) +{ + + hashtab_t p; + + p = (hashtab_t) malloc(sizeof(hashtab_val_t)); + if (p == NULL) + return p; + + memset(p, 0, sizeof(hashtab_val_t)); + p->size = size; + p->nel = 0; + p->hash_value = hash_value; + p->keycmp = keycmp; + p->htable = (hashtab_ptr_t *) calloc(size, sizeof(hashtab_ptr_t)); + if (p->htable == NULL) { + free(p); + return NULL; + } + + return p; +} + +static void hashtab_check_resize(hashtab_t h) +{ + unsigned int hvalue, i, old_size, new_size = h->size; + hashtab_ptr_t *new_htable, *dst, cur, next; + + while (new_size <= h->nel && new_size * 2 != 0) + new_size *= 2; + + if (h->size == new_size) + return; + + new_htable = calloc(new_size, sizeof(*new_htable)); + if (!new_htable) + return; + + old_size = h->size; + h->size = new_size; + + /* Move all elements to the new htable */ + for (i = 0; i < old_size; i++) { + cur = h->htable[i]; + while (cur != NULL) { + hvalue = h->hash_value(h, cur->key); + dst = &new_htable[hvalue]; + while (*dst && h->keycmp(h, cur->key, (*dst)->key) > 0) + dst = &(*dst)->next; + + next = cur->next; + + cur->next = *dst; + *dst = cur; + + cur = next; + } + } + free(h->htable); + h->htable = new_htable; +} + +int hashtab_insert(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum) +{ + int hvalue; + hashtab_ptr_t prev, cur, newnode; + + if (!h) + return SEPOL_ENOMEM; + + hashtab_check_resize(h); + + hvalue = h->hash_value(h, key); + prev = NULL; + cur = h->htable[hvalue]; + while (cur && h->keycmp(h, key, cur->key) > 0) { + prev = cur; + cur = cur->next; + } + + if (cur && (h->keycmp(h, key, cur->key) == 0)) + return SEPOL_EEXIST; + + newnode = (hashtab_ptr_t) malloc(sizeof(hashtab_node_t)); + if (newnode == NULL) + return SEPOL_ENOMEM; + memset(newnode, 0, sizeof(struct hashtab_node)); + newnode->key = key; + newnode->datum = datum; + if (prev) { + newnode->next = prev->next; + prev->next = newnode; + } else { + newnode->next = h->htable[hvalue]; + h->htable[hvalue] = newnode; + } + + h->nel++; + return SEPOL_OK; +} + +int hashtab_remove(hashtab_t h, hashtab_key_t key, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, void *args), void *args) +{ + int hvalue; + hashtab_ptr_t cur, last; + + if (!h) + return SEPOL_ENOENT; + + hvalue = h->hash_value(h, key); + last = NULL; + cur = h->htable[hvalue]; + while (cur != NULL && h->keycmp(h, key, cur->key) > 0) { + last = cur; + cur = cur->next; + } + + if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) + return SEPOL_ENOENT; + + if (last == NULL) + h->htable[hvalue] = cur->next; + else + last->next = cur->next; + + if (destroy) + destroy(cur->key, cur->datum, args); + free(cur); + h->nel--; + return SEPOL_OK; +} + +hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t key) +{ + + int hvalue; + hashtab_ptr_t cur; + + if (!h) + return NULL; + + hvalue = h->hash_value(h, key); + cur = h->htable[hvalue]; + while (cur != NULL && h->keycmp(h, key, cur->key) > 0) + cur = cur->next; + + if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) + return NULL; + + return cur->datum; +} + +void ksu_hashtab_destroy(hashtab_t h) +{ + unsigned int i; + hashtab_ptr_t cur, temp; + + if (!h) + return; + + for (i = 0; i < h->size; i++) { + cur = h->htable[i]; + while (cur != NULL) { + temp = cur; + cur = cur->next; + free(temp); + } + h->htable[i] = NULL; + } + + free(h->htable); + h->htable = NULL; + + free(h); +} + +int ksu_hashtab_map(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, void *args), void *args) +{ + unsigned int i; + hashtab_ptr_t cur; + int ret; + + if (!h) + return SEPOL_OK; + + for (i = 0; i < h->size; i++) { + cur = h->htable[i]; + while (cur != NULL) { + ret = apply(cur->key, cur->datum, args); + if (ret) + return ret; + cur = cur->next; + } + } + return SEPOL_OK; +} + +void hashtab_hash_eval(hashtab_t h, char *tag) +{ + unsigned int i; + int chain_len, slots_used, max_chain_len; + hashtab_ptr_t cur; + + slots_used = 0; + max_chain_len = 0; + for (i = 0; i < h->size; i++) { + cur = h->htable[i]; + if (cur) { + slots_used++; + chain_len = 0; + while (cur) { + chain_len++; + cur = cur->next; + } + + if (chain_len > max_chain_len) + max_chain_len = chain_len; + } + } + + printf + ("%s: %d entries and %d/%d buckets used, longest chain length %d\n", + tag, h->nel, slots_used, h->size, max_chain_len); +} diff --git a/kernel/libsepol/src/hashtab.o b/kernel/libsepol/src/hashtab.o new file mode 100644 index 00000000..305e6e2f Binary files /dev/null and b/kernel/libsepol/src/hashtab.o differ diff --git a/kernel/libsepol/src/hierarchy.c b/kernel/libsepol/src/hierarchy.c new file mode 100644 index 00000000..488dd357 --- /dev/null +++ b/kernel/libsepol/src/hierarchy.c @@ -0,0 +1,698 @@ +/* Authors: Joshua Brindle + * Jason Tang + * + * Updates: KaiGai Kohei + * adds checks based on newer boundary facility. + * + * A set of utility functions that aid policy decision when dealing + * with hierarchal namespaces. + * + * Copyright (C) 2005 Tresys Technology, LLC + * + * Copyright (c) 2008 NEC Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +// #include +// #include +#include +#include +#include +#include +#include + +#include "debug.h" + +#define BOUNDS_AVTAB_SIZE 1024 + +static int bounds_insert_helper(sepol_handle_t *handle, avtab_t *avtab, + avtab_key_t *avtab_key, avtab_datum_t *datum) +{ + int rc = avtab_insert(avtab, avtab_key, datum); + if (rc) { + if (rc == SEPOL_ENOMEM) + ERR(handle, "Insufficient memory"); + else + ERR(handle, "Unexpected error (%d)", rc); + } + return rc; +} + + +static int bounds_insert_rule(sepol_handle_t *handle, avtab_t *avtab, + avtab_t *global, avtab_t *other, + avtab_key_t *avtab_key, avtab_datum_t *datum) +{ + int rc = 0; + avtab_datum_t *dup = ksu_avtab_search(avtab, avtab_key); + + if (!dup) { + rc = bounds_insert_helper(handle, avtab, avtab_key, datum); + if (rc) goto exit; + } else { + dup->data |= datum->data; + } + + if (other) { + /* Search the other conditional avtab for the key and + * add any common permissions to the global avtab + */ + uint32_t data = 0; + dup = ksu_avtab_search(other, avtab_key); + if (dup) { + data = dup->data & datum->data; + if (data) { + dup = ksu_avtab_search(global, avtab_key); + if (!dup) { + avtab_datum_t d; + d.data = data; + rc = bounds_insert_helper(handle, global, + avtab_key, &d); + if (rc) goto exit; + } else { + dup->data |= data; + } + } + } + } + +exit: + return rc; +} + +static int bounds_expand_rule(sepol_handle_t *handle, policydb_t *p, + avtab_t *avtab, avtab_t *global, avtab_t *other, + uint32_t parent, uint32_t src, uint32_t tgt, + uint32_t class, uint32_t data) +{ + int rc = 0; + avtab_key_t avtab_key; + avtab_datum_t datum; + ebitmap_node_t *tnode; + unsigned int i; + + avtab_key.specified = AVTAB_ALLOWED; + avtab_key.target_class = class; + datum.data = data; + + if (ksu_ebitmap_get_bit(&p->attr_type_map[src - 1], parent - 1)) { + avtab_key.source_type = parent; + ebitmap_for_each_positive_bit(&p->attr_type_map[tgt - 1], tnode, i) { + avtab_key.target_type = i + 1; + rc = bounds_insert_rule(handle, avtab, global, other, + &avtab_key, &datum); + if (rc) goto exit; + } + } + +exit: + return rc; +} + +static int bounds_expand_cond_rules(sepol_handle_t *handle, policydb_t *p, + cond_av_list_t *cur, avtab_t *avtab, + avtab_t *global, avtab_t *other, + uint32_t parent) +{ + int rc = 0; + + for (; cur; cur = cur->next) { + avtab_ptr_t n = cur->node; + rc = bounds_expand_rule(handle, p, avtab, global, other, parent, + n->key.source_type, n->key.target_type, + n->key.target_class, n->datum.data); + if (rc) goto exit; + } + +exit: + return rc; +} + +struct bounds_expand_args { + sepol_handle_t *handle; + policydb_t *p; + avtab_t *avtab; + uint32_t parent; +}; + +static int bounds_expand_rule_callback(avtab_key_t *k, avtab_datum_t *d, + void *args) +{ + struct bounds_expand_args *a = (struct bounds_expand_args *)args; + + if (!(k->specified & AVTAB_ALLOWED)) + return 0; + + return bounds_expand_rule(a->handle, a->p, a->avtab, NULL, NULL, + a->parent, k->source_type, k->target_type, + k->target_class, d->data); +} + +struct bounds_cond_info { + avtab_t true_avtab; + avtab_t false_avtab; + cond_list_t *cond_list; + struct bounds_cond_info *next; +}; + +static void bounds_destroy_cond_info(struct bounds_cond_info *cur) +{ + struct bounds_cond_info *next; + + for (; cur; cur = next) { + next = cur->next; + ksu_avtab_destroy(&cur->true_avtab); + ksu_avtab_destroy(&cur->false_avtab); + cur->next = NULL; + free(cur); + } +} + +static int bounds_expand_parent_rules(sepol_handle_t *handle, policydb_t *p, + avtab_t *global_avtab, + struct bounds_cond_info **cond_info, + uint32_t parent) +{ + int rc = 0; + struct bounds_expand_args args; + cond_list_t *cur; + + ksu_avtab_init(global_avtab); + rc = ksu_avtab_alloc(global_avtab, BOUNDS_AVTAB_SIZE); + if (rc) goto oom; + + args.handle = handle; + args.p = p; + args.avtab = global_avtab; + args.parent = parent; + rc = avtab_map(&p->te_avtab, bounds_expand_rule_callback, &args); + if (rc) goto exit; + + *cond_info = NULL; + for (cur = p->cond_list; cur; cur = cur->next) { + struct bounds_cond_info *ci; + ci = malloc(sizeof(struct bounds_cond_info)); + if (!ci) goto oom; + ksu_avtab_init(&ci->true_avtab); + ksu_avtab_init(&ci->false_avtab); + ci->cond_list = cur; + ci->next = *cond_info; + *cond_info = ci; + if (cur->true_list) { + rc = ksu_avtab_alloc(&ci->true_avtab, BOUNDS_AVTAB_SIZE); + if (rc) goto oom; + rc = bounds_expand_cond_rules(handle, p, cur->true_list, + &ci->true_avtab, NULL, + NULL, parent); + if (rc) goto exit; + } + if (cur->false_list) { + rc = ksu_avtab_alloc(&ci->false_avtab, BOUNDS_AVTAB_SIZE); + if (rc) goto oom; + rc = bounds_expand_cond_rules(handle, p, cur->false_list, + &ci->false_avtab, + global_avtab, + &ci->true_avtab, parent); + if (rc) goto exit; + } + } + + return 0; + +oom: + ERR(handle, "Insufficient memory"); + +exit: + ERR(handle,"Failed to expand parent rules"); + ksu_avtab_destroy(global_avtab); + bounds_destroy_cond_info(*cond_info); + *cond_info = NULL; + return rc; +} + +static int bounds_not_covered(avtab_t *global_avtab, avtab_t *cur_avtab, + avtab_key_t *avtab_key, uint32_t data) +{ + avtab_datum_t *datum = ksu_avtab_search(cur_avtab, avtab_key); + if (datum) + data &= ~datum->data; + if (global_avtab && data) { + datum = ksu_avtab_search(global_avtab, avtab_key); + if (datum) + data &= ~datum->data; + } + + return data; +} + +static int bounds_add_bad(sepol_handle_t *handle, uint32_t src, uint32_t tgt, + uint32_t class, uint32_t data, avtab_ptr_t *bad) +{ + struct avtab_node *new = malloc(sizeof(struct avtab_node)); + if (new == NULL) { + ERR(handle, "Insufficient memory"); + return SEPOL_ENOMEM; + } + memset(new, 0, sizeof(struct avtab_node)); + new->key.source_type = src; + new->key.target_type = tgt; + new->key.target_class = class; + new->datum.data = data; + new->next = *bad; + *bad = new; + + return 0; +} + +static int bounds_check_rule(sepol_handle_t *handle, policydb_t *p, + avtab_t *global_avtab, avtab_t *cur_avtab, + uint32_t child, uint32_t parent, uint32_t src, + uint32_t tgt, uint32_t class, uint32_t data, + avtab_ptr_t *bad, int *numbad) +{ + int rc = 0; + avtab_key_t avtab_key; + type_datum_t *td; + ebitmap_node_t *tnode; + unsigned int i; + uint32_t d; + + avtab_key.specified = AVTAB_ALLOWED; + avtab_key.target_class = class; + + if (ksu_ebitmap_get_bit(&p->attr_type_map[src - 1], child - 1)) { + avtab_key.source_type = parent; + ebitmap_for_each_positive_bit(&p->attr_type_map[tgt - 1], tnode, i) { + td = p->type_val_to_struct[i]; + if (td && td->bounds) { + avtab_key.target_type = td->bounds; + d = bounds_not_covered(global_avtab, cur_avtab, + &avtab_key, data); + } else { + avtab_key.target_type = i + 1; + d = bounds_not_covered(global_avtab, cur_avtab, + &avtab_key, data); + } + if (d) { + (*numbad)++; + rc = bounds_add_bad(handle, child, i+1, class, d, bad); + if (rc) goto exit; + } + } + } + +exit: + return rc; +} + +static int bounds_check_cond_rules(sepol_handle_t *handle, policydb_t *p, + avtab_t *global_avtab, avtab_t *cond_avtab, + cond_av_list_t *rules, uint32_t child, + uint32_t parent, avtab_ptr_t *bad, + int *numbad) +{ + int rc = 0; + cond_av_list_t *cur; + + for (cur = rules; cur; cur = cur->next) { + avtab_ptr_t ap = cur->node; + avtab_key_t *key = &ap->key; + avtab_datum_t *datum = &ap->datum; + if (!(key->specified & AVTAB_ALLOWED)) + continue; + rc = bounds_check_rule(handle, p, global_avtab, cond_avtab, + child, parent, key->source_type, + key->target_type, key->target_class, + datum->data, bad, numbad); + if (rc) goto exit; + } + +exit: + return rc; +} + +struct bounds_check_args { + sepol_handle_t *handle; + policydb_t *p; + avtab_t *cur_avtab; + uint32_t child; + uint32_t parent; + avtab_ptr_t bad; + int numbad; +}; + +static int bounds_check_rule_callback(avtab_key_t *k, avtab_datum_t *d, + void *args) +{ + struct bounds_check_args *a = (struct bounds_check_args *)args; + + if (!(k->specified & AVTAB_ALLOWED)) + return 0; + + return bounds_check_rule(a->handle, a->p, NULL, a->cur_avtab, a->child, + a->parent, k->source_type, k->target_type, + k->target_class, d->data, &a->bad, &a->numbad); +} + +static int bounds_check_child_rules(sepol_handle_t *handle, policydb_t *p, + avtab_t *global_avtab, + struct bounds_cond_info *cond_info, + uint32_t child, uint32_t parent, + avtab_ptr_t *bad, int *numbad) +{ + int rc; + struct bounds_check_args args; + struct bounds_cond_info *cur; + + args.handle = handle; + args.p = p; + args.cur_avtab = global_avtab; + args.child = child; + args.parent = parent; + args.bad = NULL; + args.numbad = 0; + rc = avtab_map(&p->te_avtab, bounds_check_rule_callback, &args); + if (rc) goto exit; + + for (cur = cond_info; cur; cur = cur->next) { + cond_list_t *node = cur->cond_list; + rc = bounds_check_cond_rules(handle, p, global_avtab, + &cur->true_avtab, + node->true_list, child, parent, + &args.bad, &args.numbad); + if (rc) goto exit; + + rc = bounds_check_cond_rules(handle, p, global_avtab, + &cur->false_avtab, + node->false_list, child, parent, + &args.bad, &args.numbad); + if (rc) goto exit; + } + + *numbad += args.numbad; + *bad = args.bad; + +exit: + return rc; +} + +int bounds_check_type(sepol_handle_t *handle, policydb_t *p, uint32_t child, + uint32_t parent, avtab_ptr_t *bad, int *numbad) +{ + int rc = 0; + avtab_t global_avtab; + struct bounds_cond_info *cond_info = NULL; + + rc = bounds_expand_parent_rules(handle, p, &global_avtab, &cond_info, parent); + if (rc) goto exit; + + rc = bounds_check_child_rules(handle, p, &global_avtab, cond_info, + child, parent, bad, numbad); + + bounds_destroy_cond_info(cond_info); + ksu_avtab_destroy(&global_avtab); + +exit: + return rc; +} + +struct bounds_args { + sepol_handle_t *handle; + policydb_t *p; + int numbad; +}; + +static void bounds_report(sepol_handle_t *handle, policydb_t *p, uint32_t child, + uint32_t parent, avtab_ptr_t cur) +{ + ERR(handle, "Child type %s exceeds bounds of parent %s in the following rules:", + p->p_type_val_to_name[child - 1], + p->p_type_val_to_name[parent - 1]); + for (; cur; cur = cur->next) { + ERR(handle, " %s %s : %s { %s }", + p->p_type_val_to_name[cur->key.source_type - 1], + p->p_type_val_to_name[cur->key.target_type - 1], + p->p_class_val_to_name[cur->key.target_class - 1], + sepol_av_to_string(p, cur->key.target_class, + cur->datum.data)); + } +} + +void bounds_destroy_bad(avtab_ptr_t cur) +{ + avtab_ptr_t next; + + for (; cur; cur = next) { + next = cur->next; + cur->next = NULL; + free(cur); + } +} + +static int bounds_check_type_callback(hashtab_key_t k __attribute__ ((unused)), + hashtab_datum_t d, void *args) +{ + int rc = 0; + struct bounds_args *a = (struct bounds_args *)args; + type_datum_t *t = (type_datum_t *)d; + avtab_ptr_t bad = NULL; + + if (t->bounds) { + rc = bounds_check_type(a->handle, a->p, t->s.value, t->bounds, + &bad, &a->numbad); + if (bad) { + bounds_report(a->handle, a->p, t->s.value, t->bounds, + bad); + bounds_destroy_bad(bad); + } + } + + return rc; +} + +int bounds_check_types(sepol_handle_t *handle, policydb_t *p) +{ + int rc; + struct bounds_args args; + + args.handle = handle; + args.p = p; + args.numbad = 0; + + rc = ksu_hashtab_map(p->p_types.table, bounds_check_type_callback, &args); + if (rc) goto exit; + + if (args.numbad > 0) { + ERR(handle, "%d errors found during type bounds check", + args.numbad); + rc = SEPOL_ERR; + } + +exit: + return rc; +} + +/* The role bounds is defined as: a child role cannot have a type that + * its parent doesn't have. + */ +static int bounds_check_role_callback(hashtab_key_t k, + hashtab_datum_t d, void *args) +{ + struct bounds_args *a = (struct bounds_args *)args; + role_datum_t *r = (role_datum_t *) d; + role_datum_t *rp = NULL; + + if (!r->bounds) + return 0; + + rp = a->p->role_val_to_struct[r->bounds - 1]; + + if (rp && !ksu_ebitmap_contains(&rp->types.types, &r->types.types)) { + ERR(a->handle, "Role bounds violation, %s exceeds %s", + (char *)k, a->p->p_role_val_to_name[rp->s.value - 1]); + a->numbad++; + } + + return 0; +} + +int bounds_check_roles(sepol_handle_t *handle, policydb_t *p) +{ + struct bounds_args args; + + args.handle = handle; + args.p = p; + args.numbad = 0; + + ksu_hashtab_map(p->p_roles.table, bounds_check_role_callback, &args); + + if (args.numbad > 0) { + ERR(handle, "%d errors found during role bounds check", + args.numbad); + return SEPOL_ERR; + } + + return 0; +} + +/* The user bounds is defined as: a child user cannot have a role that + * its parent doesn't have. + */ +static int bounds_check_user_callback(hashtab_key_t k, + hashtab_datum_t d, void *args) +{ + struct bounds_args *a = (struct bounds_args *)args; + user_datum_t *u = (user_datum_t *) d; + user_datum_t *up = NULL; + + if (!u->bounds) + return 0; + + up = a->p->user_val_to_struct[u->bounds - 1]; + + if (up && !ksu_ebitmap_contains(&up->roles.roles, &u->roles.roles)) { + ERR(a->handle, "User bounds violation, %s exceeds %s", + (char *) k, a->p->p_user_val_to_name[up->s.value - 1]); + a->numbad++; + } + + return 0; +} + +int bounds_check_users(sepol_handle_t *handle, policydb_t *p) +{ + struct bounds_args args; + + args.handle = handle; + args.p = p; + args.numbad = 0; + + ksu_hashtab_map(p->p_users.table, bounds_check_user_callback, &args); + + if (args.numbad > 0) { + ERR(handle, "%d errors found during user bounds check", + args.numbad); + return SEPOL_ERR; + } + + return 0; +} + +#define add_hierarchy_callback_template(prefix) \ + int hierarchy_add_##prefix##_callback(hashtab_key_t k __attribute__ ((unused)), \ + hashtab_datum_t d, void *args) \ +{ \ + struct bounds_args *a = (struct bounds_args *)args; \ + sepol_handle_t *handle = a->handle; \ + policydb_t *p = a->p; \ + prefix##_datum_t *datum = (prefix##_datum_t *)d; \ + prefix##_datum_t *parent; \ + char *parent_name, *datum_name, *tmp; \ + \ + if (!datum->bounds) { \ + datum_name = p->p_##prefix##_val_to_name[datum->s.value - 1]; \ + \ + tmp = strrchr(datum_name, '.'); \ + /* no '.' means it has no parent */ \ + if (!tmp) return 0; \ + \ + parent_name = strdup(datum_name); \ + if (!parent_name) { \ + ERR(handle, "Insufficient memory"); \ + return SEPOL_ENOMEM; \ + } \ + parent_name[tmp - datum_name] = '\0'; \ + \ + parent = hashtab_search(p->p_##prefix##s.table, parent_name); \ + if (!parent) { \ + /* Orphan type/role/user */ \ + ERR(handle, "%s doesn't exist, %s is an orphan",\ + parent_name, \ + p->p_##prefix##_val_to_name[datum->s.value - 1]); \ + free(parent_name); \ + a->numbad++; \ + return 0; \ + } \ + datum->bounds = parent->s.value; \ + free(parent_name); \ + } \ + \ + return 0; \ +} \ + +static add_hierarchy_callback_template(type) +static add_hierarchy_callback_template(role) +static add_hierarchy_callback_template(user) + +int hierarchy_add_bounds(sepol_handle_t *handle, policydb_t *p) +{ + int rc = 0; + struct bounds_args args; + + args.handle = handle; + args.p = p; + args.numbad = 0; + + rc = ksu_hashtab_map(p->p_users.table, hierarchy_add_user_callback, &args); + if (rc) goto exit; + + rc = ksu_hashtab_map(p->p_roles.table, hierarchy_add_role_callback, &args); + if (rc) goto exit; + + rc = ksu_hashtab_map(p->p_types.table, hierarchy_add_type_callback, &args); + if (rc) goto exit; + + if (args.numbad > 0) { + ERR(handle, "%d errors found while adding hierarchies", + args.numbad); + rc = SEPOL_ERR; + } + +exit: + return rc; +} + +int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p) +{ + int rc = 0; + int violation = 0; + + rc = hierarchy_add_bounds(handle, p); + if (rc) goto exit; + + rc = bounds_check_users(handle, p); + if (rc) + violation = 1; + + rc = bounds_check_roles(handle, p); + if (rc) + violation = 1; + + rc = bounds_check_types(handle, p); + if (rc) { + if (rc == SEPOL_ERR) + violation = 1; + else + goto exit; + } + + if (violation) + rc = SEPOL_ERR; + +exit: + return rc; +} diff --git a/kernel/libsepol/src/hierarchy.o b/kernel/libsepol/src/hierarchy.o new file mode 100644 index 00000000..dc21f25f Binary files /dev/null and b/kernel/libsepol/src/hierarchy.o differ diff --git a/kernel/libsepol/src/ibendport_internal.h b/kernel/libsepol/src/ibendport_internal.h new file mode 100644 index 00000000..8bfb499e --- /dev/null +++ b/kernel/libsepol/src/ibendport_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_IBENDPORT_INTERNAL_H_ +#define _SEPOL_IBENDPORT_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/ibendport_record.c b/kernel/libsepol/src/ibendport_record.c new file mode 100644 index 00000000..8c9c3d2d --- /dev/null +++ b/kernel/libsepol/src/ibendport_record.c @@ -0,0 +1,285 @@ +// #include +#include +#include +#include +// #include + +#include "sepol/policydb/policydb.h" +#include "ibendport_internal.h" +#include "context_internal.h" +#include "debug.h" + +struct sepol_ibendport { + /* Device Name */ + char *ibdev_name; + + /* Port number */ + int port; + + /* Context */ + sepol_context_t *con; +}; + +struct sepol_ibendport_key { + /* Device Name */ + char *ibdev_name; + + /* Port number */ + int port; +}; + +/* Allocates a sufficiently large string (ibdev_name) */ +int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle, + char **ibdev_name) +{ + *ibdev_name = calloc(1, IB_DEVICE_NAME_MAX); + + if (!*ibdev_name) + goto omem; + + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + ERR(handle, "could not allocate string buffer for ibdev_name"); + return STATUS_ERR; +} + +/* Key */ +int sepol_ibendport_key_create(sepol_handle_t *handle, + const char *ibdev_name, + int port, + sepol_ibendport_key_t **key_ptr) +{ + sepol_ibendport_key_t *tmp_key = + (sepol_ibendport_key_t *)malloc(sizeof(sepol_ibendport_key_t)); + + if (!tmp_key) { + ERR(handle, "out of memory, could not create ibendport key"); + goto omem; + } + + if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_key->ibdev_name) < 0) + goto err; + + strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX - 1); + tmp_key->port = port; + + *key_ptr = tmp_key; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + sepol_ibendport_key_free(tmp_key); + ERR(handle, "could not create ibendport key for IB device %s, port %u", + ibdev_name, port); + return STATUS_ERR; +} + + +void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key, + const char **ibdev_name, int *port) +{ + *ibdev_name = key->ibdev_name; + *port = key->port; +} + + +int sepol_ibendport_key_extract(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_key_t **key_ptr) +{ + if (sepol_ibendport_key_create + (handle, ibendport->ibdev_name, ibendport->port, key_ptr) < 0) { + ERR(handle, "could not extract key from ibendport device %s port %d", + ibendport->ibdev_name, + ibendport->port); + + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_ibendport_key_free(sepol_ibendport_key_t *key) +{ + if (!key) + return; + free(key->ibdev_name); + free(key); +} + +int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, const sepol_ibendport_key_t *key) +{ + int rc; + + rc = strcmp(ibendport->ibdev_name, key->ibdev_name); + + if ((ibendport->port == key->port) && !rc) + return 0; + + if (ibendport->port < key->port) + return -1; + else if (key->port < ibendport->port) + return 1; + else + return rc; +} + +int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, const sepol_ibendport_t *ibendport2) +{ + int rc; + + rc = strcmp(ibendport->ibdev_name, ibendport2->ibdev_name); + + if ((ibendport->port == ibendport2->port) && !rc) + return 0; + + if (ibendport->port < ibendport2->port) + return -1; + else if (ibendport2->port < ibendport->port) + return 1; + else + return rc; +} + +int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport) +{ + return ibendport->port; +} + + +void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port) +{ + ibendport->port = port; +} + + +int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + char **ibdev_name) +{ + char *tmp_ibdev_name = NULL; + + if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0) + goto err; + + strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1); + *ibdev_name = tmp_ibdev_name; + return STATUS_SUCCESS; + +err: + free(tmp_ibdev_name); + ERR(handle, "could not get ibendport ibdev_name"); + return STATUS_ERR; +} + + +int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, + const char *ibdev_name) +{ + char *tmp = NULL; + + if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0) + goto err; + + strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX - 1); + free(ibendport->ibdev_name); + ibendport->ibdev_name = tmp; + return STATUS_SUCCESS; + +err: + free(tmp); + ERR(handle, "could not set ibendport subnet prefix to %s", ibdev_name); + return STATUS_ERR; +} + + +/* Create */ +int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport) +{ + sepol_ibendport_t *tmp_ibendport = (sepol_ibendport_t *)malloc(sizeof(sepol_ibendport_t)); + + if (!tmp_ibendport) { + ERR(handle, "out of memory, could not create ibendport record"); + return STATUS_ERR; + } + + tmp_ibendport->ibdev_name = NULL; + tmp_ibendport->port = 0; + tmp_ibendport->con = NULL; + *ibendport = tmp_ibendport; + + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_ibendport_clone(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_t **ibendport_ptr) +{ + sepol_ibendport_t *new_ibendport = NULL; + + if (sepol_ibendport_create(handle, &new_ibendport) < 0) + goto err; + + if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0) + goto omem; + + strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1); + new_ibendport->port = ibendport->port; + + if (ibendport->con && + (sepol_context_clone(handle, ibendport->con, &new_ibendport->con) < 0)) + goto err; + + *ibendport_ptr = new_ibendport; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + ERR(handle, "could not clone ibendport record"); + sepol_ibendport_free(new_ibendport); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_ibendport_free(sepol_ibendport_t *ibendport) +{ + if (!ibendport) + return; + + free(ibendport->ibdev_name); + sepol_context_free(ibendport->con); + free(ibendport); +} + + +/* Context */ +sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport) +{ + return ibendport->con; +} + + +int sepol_ibendport_set_con(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, sepol_context_t *con) +{ + sepol_context_t *newcon; + + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set ibendport context"); + return STATUS_ERR; + } + + sepol_context_free(ibendport->con); + ibendport->con = newcon; + return STATUS_SUCCESS; +} + diff --git a/kernel/libsepol/src/ibendports.c b/kernel/libsepol/src/ibendports.c new file mode 100644 index 00000000..ee5cb193 --- /dev/null +++ b/kernel/libsepol/src/ibendports.c @@ -0,0 +1,254 @@ +#include +#include + +#include "debug.h" +#include "context.h" +#include "handle.h" + +#include +#include "ibendport_internal.h" + +/* Create a low level ibendport structure from + * a high level representation + */ +static int ibendport_from_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t **ibendport, + const sepol_ibendport_t *data) +{ + ocontext_t *tmp_ibendport = NULL; + context_struct_t *tmp_con = NULL; + char *ibdev_name = NULL; + int port = sepol_ibendport_get_port(data); + + tmp_ibendport = (ocontext_t *)calloc(1, sizeof(ocontext_t)); + if (!tmp_ibendport) + goto omem; + + if (sepol_ibendport_alloc_ibdev_name(handle, + &tmp_ibendport->u.ibendport.dev_name) < 0) + goto omem; + + if (sepol_ibendport_get_ibdev_name(handle, + data, + &ibdev_name) < 0) + goto err; + + strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX - 1); + + free(ibdev_name); + ibdev_name = NULL; + + tmp_ibendport->u.ibendport.port = port; + + /* Context */ + if (context_from_record(handle, policydb, &tmp_con, + sepol_ibendport_get_con(data)) < 0) + goto err; + context_cpy(&tmp_ibendport->context[0], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + *ibendport = tmp_ibendport; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + if (tmp_ibendport) { + context_destroy(&tmp_ibendport->context[0]); + free(tmp_ibendport); + } + context_destroy(tmp_con); + free(tmp_con); + free(ibdev_name); + ERR(handle, "could not create ibendport structure"); + return STATUS_ERR; +} + +static int ibendport_to_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t *ibendport, + sepol_ibendport_t **record) +{ + int port = ibendport->u.ibendport.port; + context_struct_t *con = &ibendport->context[0]; + + sepol_context_t *tmp_con = NULL; + sepol_ibendport_t *tmp_record = NULL; + + if (sepol_ibendport_create(handle, &tmp_record) < 0) + goto err; + + if (sepol_ibendport_set_ibdev_name(handle, tmp_record, + ibendport->u.ibendport.dev_name) < 0) + goto err; + + sepol_ibendport_set_port(tmp_record, port); + + if (context_to_record(handle, policydb, con, &tmp_con) < 0) + goto err; + + if (sepol_ibendport_set_con(handle, tmp_record, tmp_con) < 0) + goto err; + + sepol_context_free(tmp_con); + *record = tmp_record; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not convert ibendport to record"); + sepol_context_free(tmp_con); + sepol_ibendport_free(tmp_record); + return STATUS_ERR; +} + +/* Return the number of ibendports */ +extern int sepol_ibendport_count(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, unsigned int *response) +{ + unsigned int count = 0; + ocontext_t *c, *head; + const policydb_t *policydb = &p->p; + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) + count++; + + *response = count; + + return STATUS_SUCCESS; +} + +/* Check if a ibendport exists */ +int sepol_ibendport_exists(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, + const sepol_ibendport_key_t *key, int *response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int port; + const char *ibdev_name; + + sepol_ibendport_key_unpack(key, &ibdev_name, &port); + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) { + const char *ibdev_name2 = c->u.ibendport.dev_name; + int port2 = c->u.ibendport.port; + + if (port2 == port && + (!strcmp(ibdev_name, ibdev_name2))) { + *response = 1; + return STATUS_SUCCESS; + } + } + + *response = 0; + return STATUS_SUCCESS; +} + +int sepol_ibendport_query(sepol_handle_t *handle, + const sepol_policydb_t *p, + const sepol_ibendport_key_t *key, + sepol_ibendport_t **response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int port; + const char *ibdev_name; + + sepol_ibendport_key_unpack(key, &ibdev_name, &port); + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) { + const char *ibdev_name2 = c->u.ibendport.dev_name; + int port2 = c->u.ibendport.port; + + if (port2 == port && + (!strcmp(ibdev_name, ibdev_name2))) { + if (ibendport_to_record(handle, policydb, c, response) < 0) + goto err; + return STATUS_SUCCESS; + } + } + + *response = NULL; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not query ibendport, IB device: %s port %u", + ibdev_name, port); + return STATUS_ERR; +} + +/* Load a ibendport into policy */ +int sepol_ibendport_modify(sepol_handle_t *handle, + sepol_policydb_t *p, + const sepol_ibendport_key_t *key, + const sepol_ibendport_t *data) +{ + policydb_t *policydb = &p->p; + ocontext_t *ibendport = NULL; + int port; + const char *ibdev_name; + + sepol_ibendport_key_unpack(key, &ibdev_name, &port); + + if (ibendport_from_record(handle, policydb, &ibendport, data) < 0) + goto err; + + /* Attach to context list */ + ibendport->next = policydb->ocontexts[OCON_IBENDPORT]; + policydb->ocontexts[OCON_IBENDPORT] = ibendport; + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not load ibendport %s/%d", + ibdev_name, port); + if (ibendport) { + context_destroy(&ibendport->context[0]); + free(ibendport); + } + return STATUS_ERR; +} + +int sepol_ibendport_iterate(sepol_handle_t *handle, + const sepol_policydb_t *p, + int (*fn)(const sepol_ibendport_t *ibendport, + void *fn_arg), void *arg) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + sepol_ibendport_t *ibendport = NULL; + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) { + int status; + + if (ibendport_to_record(handle, policydb, c, &ibendport) < 0) + goto err; + + /* Invoke handler */ + status = fn(ibendport, arg); + if (status < 0) + goto err; + + sepol_ibendport_free(ibendport); + ibendport = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not iterate over ibendports"); + sepol_ibendport_free(ibendport); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/ibpkey_internal.h b/kernel/libsepol/src/ibpkey_internal.h new file mode 100644 index 00000000..b875f942 --- /dev/null +++ b/kernel/libsepol/src/ibpkey_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_IBPKEY_INTERNAL_H_ +#define _SEPOL_IBPKEY_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/ibpkey_record.c b/kernel/libsepol/src/ibpkey_record.c new file mode 100644 index 00000000..d95e95fe --- /dev/null +++ b/kernel/libsepol/src/ibpkey_record.c @@ -0,0 +1,365 @@ +#include +#include +#include +#include +#include +#include + +#include "ibpkey_internal.h" +#include "context_internal.h" +#include "debug.h" + +struct sepol_ibpkey { + /* Subnet prefix */ + uint64_t subnet_prefix; + + /* Low - High range. Same for single ibpkeys. */ + int low, high; + + /* Context */ + sepol_context_t *con; +}; + +struct sepol_ibpkey_key { + /* Subnet prefix */ + uint64_t subnet_prefix; + + /* Low - High range. Same for single ibpkeys. */ + int low, high; +}; + +/* Converts a string represtation (subnet_prefix_str) + * to a numeric representation (subnet_prefix_bytes) + */ +static int ibpkey_parse_subnet_prefix(sepol_handle_t *handle, + const char *subnet_prefix_str, + uint64_t *subnet_prefix) +{ + struct in6_addr in_addr; + + if (inet_pton(AF_INET6, subnet_prefix_str, &in_addr) <= 0) { + ERR(handle, "could not parse IPv6 address for ibpkey subnet prefix %s: %m", + subnet_prefix_str); + return STATUS_ERR; + } + + memcpy(subnet_prefix, in_addr.s6_addr, sizeof(*subnet_prefix)); + + return STATUS_SUCCESS; +} + +/* Converts a numeric representation (subnet_prefix_bytes) + * to a string representation (subnet_prefix_str) + */ + +static int ibpkey_expand_subnet_prefix(sepol_handle_t *handle, + uint64_t subnet_prefix, + char *subnet_prefix_str) +{ + struct in6_addr addr; + + memset(&addr, 0, sizeof(struct in6_addr)); + memcpy(&addr.s6_addr[0], &subnet_prefix, sizeof(subnet_prefix)); + + if (inet_ntop(AF_INET6, &addr, subnet_prefix_str, + INET6_ADDRSTRLEN) == NULL) { + ERR(handle, + "could not expand IPv6 address to string: %m"); + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +/* Allocates a sufficiently large string (subnet_prefix) + * for an IPV6 address for the subnet prefix + */ +static int ibpkey_alloc_subnet_prefix_string(sepol_handle_t *handle, + char **subnet_prefix) +{ + char *tmp_subnet_prefix = NULL; + + tmp_subnet_prefix = malloc(INET6_ADDRSTRLEN); + + if (!tmp_subnet_prefix) + goto omem; + + *subnet_prefix = tmp_subnet_prefix; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + + ERR(handle, "could not allocate string buffer for subnet_prefix"); + return STATUS_ERR; +} + +/* Key */ +int sepol_ibpkey_key_create(sepol_handle_t *handle, + const char *subnet_prefix, + int low, int high, + sepol_ibpkey_key_t **key_ptr) +{ + sepol_ibpkey_key_t *tmp_key = + (sepol_ibpkey_key_t *)malloc(sizeof(sepol_ibpkey_key_t)); + + if (!tmp_key) { + ERR(handle, "out of memory, could not create ibpkey key"); + goto omem; + } + + if (ibpkey_parse_subnet_prefix(handle, subnet_prefix, &tmp_key->subnet_prefix) < 0) + goto err; + + tmp_key->low = low; + tmp_key->high = high; + + *key_ptr = tmp_key; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + sepol_ibpkey_key_free(tmp_key); + ERR(handle, "could not create ibpkey key for subnet prefix%s, range %u, %u", + subnet_prefix, low, high); + return STATUS_ERR; +} + + +void sepol_ibpkey_key_unpack(const sepol_ibpkey_key_t *key, + uint64_t *subnet_prefix, int *low, int *high) +{ + *subnet_prefix = key->subnet_prefix; + *low = key->low; + *high = key->high; +} + + +int sepol_ibpkey_key_extract(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + sepol_ibpkey_key_t **key_ptr) +{ + char subnet_prefix_str[INET6_ADDRSTRLEN]; + + ibpkey_expand_subnet_prefix(handle, ibpkey->subnet_prefix, subnet_prefix_str); + + if (sepol_ibpkey_key_create + (handle, subnet_prefix_str, ibpkey->low, ibpkey->high, key_ptr) < 0) { + ERR(handle, "could not extract key from ibpkey %s %d:%d", + subnet_prefix_str, + ibpkey->low, ibpkey->high); + + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_ibpkey_key_free(sepol_ibpkey_key_t *key) +{ + if (!key) + return; + free(key); +} + +int sepol_ibpkey_compare(const sepol_ibpkey_t *ibpkey, const sepol_ibpkey_key_t *key) +{ + if (ibpkey->subnet_prefix < key->subnet_prefix) + return -1; + if (key->subnet_prefix < ibpkey->subnet_prefix) + return 1; + + if (ibpkey->low < key->low) + return -1; + if (key->low < ibpkey->low) + return 1; + + if (ibpkey->high < key->high) + return -1; + if (key->high < ibpkey->high) + return 1; + + return 0; +} + +int sepol_ibpkey_compare2(const sepol_ibpkey_t *ibpkey, const sepol_ibpkey_t *ibpkey2) +{ + if (ibpkey->subnet_prefix < ibpkey2->subnet_prefix) + return -1; + if (ibpkey2->subnet_prefix < ibpkey->subnet_prefix) + return 1; + + if (ibpkey->low < ibpkey2->low) + return -1; + if (ibpkey2->low < ibpkey->low) + return 1; + + if (ibpkey->high < ibpkey2->high) + return -1; + if (ibpkey2->high < ibpkey->high) + return 1; + + return 0; +} + +/* Pkey */ +int sepol_ibpkey_get_low(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->low; +} + + +int sepol_ibpkey_get_high(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->high; +} + + +void sepol_ibpkey_set_pkey(sepol_ibpkey_t *ibpkey, int pkey_num) +{ + ibpkey->low = pkey_num; + ibpkey->high = pkey_num; +} + +void sepol_ibpkey_set_range(sepol_ibpkey_t *ibpkey, int low, int high) +{ + ibpkey->low = low; + ibpkey->high = high; +} + + +int sepol_ibpkey_get_subnet_prefix(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + char **subnet_prefix) +{ + char *tmp_subnet_prefix = NULL; + + if (ibpkey_alloc_subnet_prefix_string(handle, &tmp_subnet_prefix) < 0) + goto err; + + if (ibpkey_expand_subnet_prefix(handle, ibpkey->subnet_prefix, tmp_subnet_prefix) < 0) + goto err; + + *subnet_prefix = tmp_subnet_prefix; + return STATUS_SUCCESS; + +err: + free(tmp_subnet_prefix); + ERR(handle, "could not get ibpkey subnet_prefix"); + return STATUS_ERR; +} + + +/* Subnet prefix */ +uint64_t sepol_ibpkey_get_subnet_prefix_bytes(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->subnet_prefix; +} + + +int sepol_ibpkey_set_subnet_prefix(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, + const char *subnet_prefix_str) +{ + uint64_t tmp = 0; + + if (ibpkey_parse_subnet_prefix(handle, subnet_prefix_str, &tmp) < 0) + goto err; + + ibpkey->subnet_prefix = tmp; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not set ibpkey subnet prefix to %s", subnet_prefix_str); + return STATUS_ERR; +} + + +void sepol_ibpkey_set_subnet_prefix_bytes(sepol_ibpkey_t *ibpkey, + uint64_t subnet_prefix) +{ + ibpkey->subnet_prefix = subnet_prefix; +} + + +/* Create */ +int sepol_ibpkey_create(sepol_handle_t *handle, sepol_ibpkey_t **ibpkey) +{ + sepol_ibpkey_t *tmp_ibpkey = (sepol_ibpkey_t *)malloc(sizeof(sepol_ibpkey_t)); + + if (!tmp_ibpkey) { + ERR(handle, "out of memory, could not create ibpkey record"); + return STATUS_ERR; + } + + tmp_ibpkey->subnet_prefix = 0; + tmp_ibpkey->low = 0; + tmp_ibpkey->high = 0; + tmp_ibpkey->con = NULL; + *ibpkey = tmp_ibpkey; + + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_ibpkey_clone(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, sepol_ibpkey_t **ibpkey_ptr) +{ + sepol_ibpkey_t *new_ibpkey = NULL; + + if (sepol_ibpkey_create(handle, &new_ibpkey) < 0) + goto err; + + new_ibpkey->subnet_prefix = ibpkey->subnet_prefix; + new_ibpkey->low = ibpkey->low; + new_ibpkey->high = ibpkey->high; + + if (ibpkey->con && + (sepol_context_clone(handle, ibpkey->con, &new_ibpkey->con) < 0)) + goto err; + + *ibpkey_ptr = new_ibpkey; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not clone ibpkey record"); + sepol_ibpkey_free(new_ibpkey); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_ibpkey_free(sepol_ibpkey_t *ibpkey) +{ + if (!ibpkey) + return; + + sepol_context_free(ibpkey->con); + free(ibpkey); +} + + +/* Context */ +sepol_context_t *sepol_ibpkey_get_con(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->con; +} + + +int sepol_ibpkey_set_con(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, sepol_context_t *con) +{ + sepol_context_t *newcon; + + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set ibpkey context"); + return STATUS_ERR; + } + + sepol_context_free(ibpkey->con); + ibpkey->con = newcon; + return STATUS_SUCCESS; +} + diff --git a/kernel/libsepol/src/ibpkeys.c b/kernel/libsepol/src/ibpkeys.c new file mode 100644 index 00000000..68a9bdfe --- /dev/null +++ b/kernel/libsepol/src/ibpkeys.c @@ -0,0 +1,251 @@ +#include +#include +#include + +#include "debug.h" +#include "context.h" +#include "handle.h" + +#include +#include +#include "ibpkey_internal.h" + +/* Create a low level ibpkey structure from + * a high level representation + */ +static int ibpkey_from_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t **ibpkey, const sepol_ibpkey_t *data) +{ + ocontext_t *tmp_ibpkey = NULL; + context_struct_t *tmp_con = NULL; + char *subnet_prefix_buf = NULL; + int low = sepol_ibpkey_get_low(data); + int high = sepol_ibpkey_get_high(data); + + tmp_ibpkey = (ocontext_t *)calloc(1, sizeof(*tmp_ibpkey)); + if (!tmp_ibpkey) + goto omem; + + tmp_ibpkey->u.ibpkey.subnet_prefix = sepol_ibpkey_get_subnet_prefix_bytes(data); + + /* Pkey range */ + tmp_ibpkey->u.ibpkey.low_pkey = low; + tmp_ibpkey->u.ibpkey.high_pkey = high; + if (tmp_ibpkey->u.ibpkey.low_pkey > tmp_ibpkey->u.ibpkey.high_pkey) { + ERR(handle, "low ibpkey %d exceeds high ibpkey %d", + tmp_ibpkey->u.ibpkey.low_pkey, tmp_ibpkey->u.ibpkey.high_pkey); + goto err; + } + + /* Context */ + if (context_from_record(handle, policydb, &tmp_con, + sepol_ibpkey_get_con(data)) < 0) + goto err; + context_cpy(&tmp_ibpkey->context[0], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + *ibpkey = tmp_ibpkey; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + if (tmp_ibpkey) { + context_destroy(&tmp_ibpkey->context[0]); + free(tmp_ibpkey); + } + context_destroy(tmp_con); + free(tmp_con); + free(subnet_prefix_buf); + ERR(handle, "could not create ibpkey structure"); + return STATUS_ERR; +} + +static int ibpkey_to_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t *ibpkey, sepol_ibpkey_t **record) +{ + context_struct_t *con = &ibpkey->context[0]; + sepol_context_t *tmp_con = NULL; + sepol_ibpkey_t *tmp_record = NULL; + + if (sepol_ibpkey_create(handle, &tmp_record) < 0) + goto err; + + sepol_ibpkey_set_subnet_prefix_bytes(tmp_record, + ibpkey->u.ibpkey.subnet_prefix); + + sepol_ibpkey_set_range(tmp_record, ibpkey->u.ibpkey.low_pkey, + ibpkey->u.ibpkey.high_pkey); + + if (context_to_record(handle, policydb, con, &tmp_con) < 0) + goto err; + + if (sepol_ibpkey_set_con(handle, tmp_record, tmp_con) < 0) + goto err; + + sepol_context_free(tmp_con); + *record = tmp_record; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not convert ibpkey to record"); + sepol_context_free(tmp_con); + sepol_ibpkey_free(tmp_record); + return STATUS_ERR; +} + +/* Return the number of ibpkeys */ +extern int sepol_ibpkey_count(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, unsigned int *response) +{ + unsigned int count = 0; + ocontext_t *c, *head; + const policydb_t *policydb = &p->p; + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) + count++; + + *response = count; + + return STATUS_SUCCESS; +} + +/* Check if a ibpkey exists */ +int sepol_ibpkey_exists(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, + const sepol_ibpkey_key_t *key, int *response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int low, high; + uint64_t subnet_prefix; + + sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high); + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) { + uint64_t subnet_prefix2 = c->u.ibpkey.subnet_prefix; + uint16_t low2 = c->u.ibpkey.low_pkey; + uint16_t high2 = c->u.ibpkey.high_pkey; + + if (low2 == low && + high2 == high && + subnet_prefix == subnet_prefix2) { + *response = 1; + return STATUS_SUCCESS; + } + } + + *response = 0; + return STATUS_SUCCESS; +} + +/* Query a ibpkey */ +int sepol_ibpkey_query(sepol_handle_t *handle, + const sepol_policydb_t *p, + const sepol_ibpkey_key_t *key, sepol_ibpkey_t **response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int low, high; + uint64_t subnet_prefix; + + sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high); + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) { + uint64_t subnet_prefix2 = c->u.ibpkey.subnet_prefix; + int low2 = c->u.ibpkey.low_pkey; + int high2 = c->u.ibpkey.high_pkey; + + if (low2 == low && + high2 == high && + subnet_prefix == subnet_prefix2) { + if (ibpkey_to_record(handle, policydb, c, response) < 0) + goto err; + return STATUS_SUCCESS; + } + } + + *response = NULL; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not query ibpkey subnet prefix: %#" PRIx64 " range %u - %u exists", + subnet_prefix, low, high); + return STATUS_ERR; +} + +/* Load a ibpkey into policy */ +int sepol_ibpkey_modify(sepol_handle_t *handle, + sepol_policydb_t *p, + const sepol_ibpkey_key_t *key, const sepol_ibpkey_t *data) +{ + policydb_t *policydb = &p->p; + ocontext_t *ibpkey = NULL; + int low, high; + uint64_t subnet_prefix; + + sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high); + + if (ibpkey_from_record(handle, policydb, &ibpkey, data) < 0) + goto err; + + /* Attach to context list */ + ibpkey->next = policydb->ocontexts[OCON_IBPKEY]; + policydb->ocontexts[OCON_IBPKEY] = ibpkey; + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not load ibpkey subnet prefix: %#" PRIx64 " range %u - %u exists", + subnet_prefix, low, high); + if (ibpkey) { + context_destroy(&ibpkey->context[0]); + free(ibpkey); + } + return STATUS_ERR; +} + +int sepol_ibpkey_iterate(sepol_handle_t *handle, + const sepol_policydb_t *p, + int (*fn)(const sepol_ibpkey_t *ibpkey, + void *fn_arg), void *arg) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + sepol_ibpkey_t *ibpkey = NULL; + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) { + int status; + + if (ibpkey_to_record(handle, policydb, c, &ibpkey) < 0) + goto err; + + /* Invoke handler */ + status = fn(ibpkey, arg); + if (status < 0) + goto err; + + sepol_ibpkey_free(ibpkey); + ibpkey = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not iterate over ibpkeys"); + sepol_ibpkey_free(ibpkey); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/iface_internal.h b/kernel/libsepol/src/iface_internal.h new file mode 100644 index 00000000..82fb60cb --- /dev/null +++ b/kernel/libsepol/src/iface_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_IFACE_INTERNAL_H_ +#define _SEPOL_IFACE_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/iface_record.c b/kernel/libsepol/src/iface_record.c new file mode 100644 index 00000000..e7756989 --- /dev/null +++ b/kernel/libsepol/src/iface_record.c @@ -0,0 +1,231 @@ +#include +#include + +#include "iface_internal.h" +#include "context_internal.h" +#include "debug.h" + +struct sepol_iface { + + /* Interface name */ + char *name; + + /* Interface context */ + sepol_context_t *netif_con; + + /* Message context */ + sepol_context_t *netmsg_con; +}; + +struct sepol_iface_key { + + /* Interface name */ + char *name; +}; + +/* Key */ +int sepol_iface_key_create(sepol_handle_t * handle, + const char *name, sepol_iface_key_t ** key_ptr) +{ + + sepol_iface_key_t *tmp_key = + (sepol_iface_key_t *) malloc(sizeof(sepol_iface_key_t)); + + if (!tmp_key) { + ERR(handle, "out of memory, could not create interface key"); + return STATUS_ERR; + } + + tmp_key->name = strdup(name); + if (!tmp_key->name) { + ERR(handle, "out of memory, could not create interface key"); + free(tmp_key); + return STATUS_ERR; + } + + *key_ptr = tmp_key; + return STATUS_SUCCESS; +} + + +void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name) +{ + + *name = key->name; +} + + +int sepol_iface_key_extract(sepol_handle_t * handle, + const sepol_iface_t * iface, + sepol_iface_key_t ** key_ptr) +{ + + if (sepol_iface_key_create(handle, iface->name, key_ptr) < 0) { + ERR(handle, "could not extract key from " + "interface %s", iface->name); + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_iface_key_free(sepol_iface_key_t * key) +{ + if (!key) + return; + free(key->name); + free(key); +} + +int sepol_iface_compare(const sepol_iface_t * iface, + const sepol_iface_key_t * key) +{ + + return strcmp(iface->name, key->name); +} + +int sepol_iface_compare2(const sepol_iface_t * iface, + const sepol_iface_t * iface2) +{ + + return strcmp(iface->name, iface2->name); +} + +/* Create */ +int sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface) +{ + + sepol_iface_t *tmp_iface = + (sepol_iface_t *) malloc(sizeof(sepol_iface_t)); + + if (!tmp_iface) { + ERR(handle, "out of memory, could not create " + "interface record"); + return STATUS_ERR; + } + + tmp_iface->name = NULL; + tmp_iface->netif_con = NULL; + tmp_iface->netmsg_con = NULL; + *iface = tmp_iface; + + return STATUS_SUCCESS; +} + + +/* Name */ +const char *sepol_iface_get_name(const sepol_iface_t * iface) +{ + + return iface->name; +} + + +int sepol_iface_set_name(sepol_handle_t * handle, + sepol_iface_t * iface, const char *name) +{ + + char *tmp_name = strdup(name); + if (!tmp_name) { + ERR(handle, "out of memory, " "could not set interface name"); + return STATUS_ERR; + } + free(iface->name); + iface->name = tmp_name; + return STATUS_SUCCESS; +} + + +/* Interface Context */ +sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface) +{ + + return iface->netif_con; +} + + +int sepol_iface_set_ifcon(sepol_handle_t * handle, + sepol_iface_t * iface, sepol_context_t * con) +{ + + sepol_context_t *newcon; + + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set interface context"); + return STATUS_ERR; + } + + sepol_context_free(iface->netif_con); + iface->netif_con = newcon; + return STATUS_SUCCESS; +} + + +/* Message Context */ +sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface) +{ + + return iface->netmsg_con; +} + + +int sepol_iface_set_msgcon(sepol_handle_t * handle, + sepol_iface_t * iface, sepol_context_t * con) +{ + + sepol_context_t *newcon; + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set message context"); + return STATUS_ERR; + } + + sepol_context_free(iface->netmsg_con); + iface->netmsg_con = newcon; + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_iface_clone(sepol_handle_t * handle, + const sepol_iface_t * iface, sepol_iface_t ** iface_ptr) +{ + + sepol_iface_t *new_iface = NULL; + if (sepol_iface_create(handle, &new_iface) < 0) + goto err; + + if (sepol_iface_set_name(handle, new_iface, iface->name) < 0) + goto err; + + if (iface->netif_con && + (sepol_context_clone + (handle, iface->netif_con, &new_iface->netif_con) < 0)) + goto err; + + if (iface->netmsg_con && + (sepol_context_clone + (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0)) + goto err; + + *iface_ptr = new_iface; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not clone interface record"); + sepol_iface_free(new_iface); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_iface_free(sepol_iface_t * iface) +{ + + if (!iface) + return; + + free(iface->name); + sepol_context_free(iface->netif_con); + sepol_context_free(iface->netmsg_con); + free(iface); +} + diff --git a/kernel/libsepol/src/inet_ntop.c b/kernel/libsepol/src/inet_ntop.c new file mode 100644 index 00000000..43939103 --- /dev/null +++ b/kernel/libsepol/src/inet_ntop.c @@ -0,0 +1,398 @@ +/* $OpenBSD: inet_ntop.c,v 1.13 2016/09/21 04:38:56 guenther Exp $ */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +// #include +// #include +#include "kernel.h" + +#define INADDRSZ 4 +#define IN6ADDRSZ 16 +#define INT16SZ 2 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const u_char *src, char *dst, size_t size); +static const char *inet_ntop6(const u_char *src, char *dst, size_t size); + +/* const char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); + case AF_INET6: + return (inet_ntop6(src, dst, size)); + default: + // errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(const u_char *src, char *dst, size_t size) +{ + char tmp[sizeof "255.255.255.255"]; + int l; + + l = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u", + src[0], src[1], src[2], src[3]); + if (l <= 0 || l >= size) { + // errno = ENOSPC; + return (NULL); + } + strlcpy(dst, tmp, size); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(const u_char *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + char *tp, *ep; + struct { int base, len; } best, cur; + u_int words[IN6ADDRSZ / INT16SZ]; + int i; + int advance; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + ep = tmp + sizeof(tmp); + for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) { + if (tp + 1 >= ep) { + // errno = ENOSPC; + return (NULL); + } + *tp++ = ':'; + } + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) { + if (tp + 1 >= ep) { + // errno = ENOSPC; + return (NULL); + } + *tp++ = ':'; + } + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, ep - tp)) + return (NULL); + tp += strlen(tp); + break; + } + advance = snprintf(tp, ep - tp, "%x", words[i]); + if (advance <= 0 || advance >= ep - tp) { + // errno = ENOSPC; + return (NULL); + } + tp += advance; + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { + if (tp + 1 >= ep) { + // errno = ENOSPC; + return (NULL); + } + *tp++ = ':'; + } + if (tp + 1 >= ep) { + // errno = ENOSPC; + return (NULL); + } + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + // errno = ENOSPC; + return (NULL); + } + strlcpy(dst, tmp, size); + return (dst); +} + +// ------------------------------ + + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4(const char *src, u_char *dst); +static int inet_pton6(const char *src, u_char *dst); + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +inet_pton(int af, const char *src, void *dst) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + case AF_INET6: + return (inet_pton6(src, dst)); + default: + // errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(const char *src, u_char *dst) +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + u_char tmp[INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + u_int new = *tp * 10 + (pch - digits); + + if (new > 255) + return (0); + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + *tp = new; + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + + memcpy(dst, tmp, INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6(const char *src, u_char *dst) +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit, count_xdigit; + u_int val; + + memset((tp = tmp), '\0', IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = count_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + if (count_xdigit >= 4) + return (0); + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + count_xdigit++; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } else if (*src == '\0') { + return (0); + } + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + count_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + count_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + if (tp == endp) + return (0); + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, IN6ADDRSZ); + return (1); +} diff --git a/kernel/libsepol/src/inet_ntop.o b/kernel/libsepol/src/inet_ntop.o new file mode 100644 index 00000000..d8628cf7 Binary files /dev/null and b/kernel/libsepol/src/inet_ntop.o differ diff --git a/kernel/libsepol/src/interfaces.c b/kernel/libsepol/src/interfaces.c new file mode 100644 index 00000000..f371d0bf --- /dev/null +++ b/kernel/libsepol/src/interfaces.c @@ -0,0 +1,271 @@ +#include + +#include "debug.h" +#include "context.h" +#include "handle.h" + +#include +#include +#include "iface_internal.h" + +/* Create a low level structure from record */ +static int iface_from_record(sepol_handle_t * handle, + const policydb_t * policydb, + ocontext_t ** iface, const sepol_iface_t * record) +{ + + ocontext_t *tmp_iface = NULL; + context_struct_t *tmp_con = NULL; + + tmp_iface = (ocontext_t *) calloc(1, sizeof(ocontext_t)); + if (!tmp_iface) + goto omem; + + /* Name */ + tmp_iface->u.name = strdup(sepol_iface_get_name(record)); + if (!tmp_iface->u.name) + goto omem; + + /* Interface Context */ + if (context_from_record(handle, policydb, + &tmp_con, sepol_iface_get_ifcon(record)) < 0) + goto err; + context_cpy(&tmp_iface->context[0], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + /* Message Context */ + if (context_from_record(handle, policydb, + &tmp_con, sepol_iface_get_msgcon(record)) < 0) + goto err; + context_cpy(&tmp_iface->context[1], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + *iface = tmp_iface; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + if (tmp_iface != NULL) { + free(tmp_iface->u.name); + context_destroy(&tmp_iface->context[0]); + context_destroy(&tmp_iface->context[1]); + free(tmp_iface); + } + context_destroy(tmp_con); + free(tmp_con); + ERR(handle, "error creating interface structure"); + return STATUS_ERR; +} + +static int iface_to_record(sepol_handle_t * handle, + const policydb_t * policydb, + ocontext_t * iface, sepol_iface_t ** record) +{ + + char *name = iface->u.name; + context_struct_t *ifcon = &iface->context[0]; + context_struct_t *msgcon = &iface->context[1]; + + sepol_context_t *tmp_con = NULL; + sepol_iface_t *tmp_record = NULL; + + if (sepol_iface_create(handle, &tmp_record) < 0) + goto err; + + if (sepol_iface_set_name(handle, tmp_record, name) < 0) + goto err; + + if (context_to_record(handle, policydb, ifcon, &tmp_con) < 0) + goto err; + if (sepol_iface_set_ifcon(handle, tmp_record, tmp_con) < 0) + goto err; + sepol_context_free(tmp_con); + tmp_con = NULL; + + if (context_to_record(handle, policydb, msgcon, &tmp_con) < 0) + goto err; + if (sepol_iface_set_msgcon(handle, tmp_record, tmp_con) < 0) + goto err; + sepol_context_free(tmp_con); + tmp_con = NULL; + + *record = tmp_record; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not convert interface %s to record", name); + sepol_context_free(tmp_con); + sepol_iface_free(tmp_record); + return STATUS_ERR; +} + +/* Check if an interface exists */ +int sepol_iface_exists(sepol_handle_t * handle __attribute__ ((unused)), + const sepol_policydb_t * p, + const sepol_iface_key_t * key, int *response) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + + const char *name; + sepol_iface_key_unpack(key, &name); + + head = policydb->ocontexts[OCON_NETIF]; + for (c = head; c; c = c->next) { + if (!strcmp(name, c->u.name)) { + *response = 1; + return STATUS_SUCCESS; + } + } + *response = 0; + + return STATUS_SUCCESS; +} + +/* Query an interface */ +int sepol_iface_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_iface_key_t * key, sepol_iface_t ** response) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + + const char *name; + sepol_iface_key_unpack(key, &name); + + head = policydb->ocontexts[OCON_NETIF]; + for (c = head; c; c = c->next) { + if (!strcmp(name, c->u.name)) { + + if (iface_to_record(handle, policydb, c, response) < 0) + goto err; + + return STATUS_SUCCESS; + } + } + + *response = NULL; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not query interface %s", name); + return STATUS_ERR; +} + +/* Load an interface into policy */ +int sepol_iface_modify(sepol_handle_t * handle, + sepol_policydb_t * p, + const sepol_iface_key_t * key, + const sepol_iface_t * data) +{ + + policydb_t *policydb = &p->p; + ocontext_t *head, *prev, *c, *iface = NULL; + + const char *name; + sepol_iface_key_unpack(key, &name); + + if (iface_from_record(handle, policydb, &iface, data) < 0) + goto err; + + prev = NULL; + head = policydb->ocontexts[OCON_NETIF]; + for (c = head; c; c = c->next) { + if (!strcmp(name, c->u.name)) { + + /* Replace */ + iface->next = c->next; + if (prev == NULL) + policydb->ocontexts[OCON_NETIF] = iface; + else + prev->next = iface; + free(c->u.name); + context_destroy(&c->context[0]); + context_destroy(&c->context[1]); + free(c); + + return STATUS_SUCCESS; + } + prev = c; + } + + /* Attach to context list */ + iface->next = policydb->ocontexts[OCON_NETIF]; + policydb->ocontexts[OCON_NETIF] = iface; + return STATUS_SUCCESS; + + err: + ERR(handle, "error while loading interface %s", name); + + if (iface != NULL) { + free(iface->u.name); + context_destroy(&iface->context[0]); + context_destroy(&iface->context[1]); + free(iface); + } + return STATUS_ERR; +} + +/* Return the number of interfaces */ +extern int sepol_iface_count(sepol_handle_t * handle __attribute__ ((unused)), + const sepol_policydb_t * p, unsigned int *response) +{ + + unsigned int count = 0; + ocontext_t *c, *head; + const policydb_t *policydb = &p->p; + + head = policydb->ocontexts[OCON_NETIF]; + for (c = head; c != NULL; c = c->next) + count++; + + *response = count; + + return STATUS_SUCCESS; +} + +int sepol_iface_iterate(sepol_handle_t * handle, + const sepol_policydb_t * p, + int (*fn) (const sepol_iface_t * iface, + void *fn_arg), void *arg) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + sepol_iface_t *iface = NULL; + + head = policydb->ocontexts[OCON_NETIF]; + for (c = head; c; c = c->next) { + int status; + + if (iface_to_record(handle, policydb, c, &iface) < 0) + goto err; + + /* Invoke handler */ + status = fn(iface, arg); + if (status < 0) + goto err; + + sepol_iface_free(iface); + iface = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not iterate over interfaces"); + sepol_iface_free(iface); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/kernel.h b/kernel/libsepol/src/kernel.h new file mode 100644 index 00000000..c6b0372b --- /dev/null +++ b/kernel/libsepol/src/kernel.h @@ -0,0 +1,34 @@ +#ifndef __LIBSEPOL_H_KERNEL +#define __LIBSEPOL_H_KERNEL + +#include +#include +#include +#include + +#define malloc(size) kmalloc(size, GFP_KERNEL) +#define calloc(nitems, size) kzalloc(nitems * size, GFP_KERNEL) +#define realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL) +#define free(p) kfree(p) + +#define printf(...) printk(__VA_ARGS__) + +#define assert(...) + +#define PRIu32 "d" +#define PRIx64 "x" + +#define UINT16_MAX USHRT_MAX +#define UINT8_MAX 0xff + +#define strdup(x) kstrdup(x, GFP_KERNEL) +#define strndup(x, y) kstrndup(x, y, GFP_KERNEL) + +// http://aospxref.com/android-8.1.0_r81/xref/bionic/libc/include/sys/types.h?fi=socklen_t#109 +typedef uint32_t socklen_t; + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); + +int inet_pton(int af, const char *src, void *dst); + +#endif \ No newline at end of file diff --git a/kernel/libsepol/src/kernel_to_cil.c b/kernel/libsepol/src/kernel_to_cil.c new file mode 100644 index 00000000..fc4ae57f --- /dev/null +++ b/kernel/libsepol/src/kernel_to_cil.c @@ -0,0 +1,3467 @@ +// #include +// #include +// #include +#include +// #include +// #include +#include +// #include + +// #include +// #include +// #include +#include "kernel.h" +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kernel_to_common.h" + + +static char *cond_expr_to_str(struct policydb *pdb, struct cond_expr *expr) +{ + struct cond_expr *curr; + struct strs *stack; + char *new_val; + char *str = NULL; + int rc; + + rc = strs_stack_init(&stack); + if (rc != 0) { + goto exit; + } + + for (curr = expr; curr != NULL; curr = curr->next) { + if (curr->expr_type == COND_BOOL) { + char *val1 = pdb->p_bool_val_to_name[curr->bool - 1]; + new_val = create_str("%s", 1, val1); + } else { + const char *op; + uint32_t num_params; + char *val1 = NULL; + char *val2 = NULL; + + switch(curr->expr_type) { + case COND_NOT: op = "not"; num_params = 1; break; + case COND_OR: op = "or"; num_params = 2; break; + case COND_AND: op = "and"; num_params = 2; break; + case COND_XOR: op = "xor"; num_params = 2; break; + case COND_EQ: op = "eq"; num_params = 2; break; + case COND_NEQ: op = "neq"; num_params = 2; break; + default: + sepol_log_err("Unknown conditional operator: %i", + curr->expr_type); + goto exit; + } + + if (num_params == 2) { + val2 = strs_stack_pop(stack); + if (!val2) { + sepol_log_err("Invalid conditional expression"); + goto exit; + } + } + val1 = strs_stack_pop(stack); + if (!val1) { + sepol_log_err("Invalid conditional expression"); + free(val2); + goto exit; + } + if (num_params == 2) { + new_val = create_str("(%s %s %s)", 3, op, val1, val2); + free(val2); + } else { + new_val = create_str("(%s %s)", 2, op, val1); + } + free(val1); + } + if (!new_val) { + sepol_log_err("Invalid conditional expression"); + goto exit; + } + rc = strs_stack_push(stack, new_val); + if (rc != 0) { + sepol_log_err("Out of memory"); + goto exit; + } + } + + new_val = strs_stack_pop(stack); + if (!new_val || !strs_stack_empty(stack)) { + sepol_log_err("Invalid conditional expression"); + goto exit; + } + + str = new_val; + + strs_stack_destroy(&stack); + return str; + +exit: + if (stack) { + while ((new_val = strs_stack_pop(stack)) != NULL) { + free(new_val); + } + strs_stack_destroy(&stack); + } + + return NULL; +} + +static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr *expr, int *use_mls) +{ + struct constraint_expr *curr; + struct strs *stack = NULL; + char *new_val = NULL; + const char *op; + char *str = NULL; + int rc; + + *use_mls = 0; + + rc = strs_stack_init(&stack); + if (rc != 0) { + goto exit; + } + + for (curr = expr; curr; curr = curr->next) { + if (curr->expr_type == CEXPR_ATTR || curr->expr_type == CEXPR_NAMES) { + const char *attr1 = NULL; + const char *attr2 = NULL; + + switch (curr->op) { + case CEXPR_EQ: op = "eq"; break; + case CEXPR_NEQ: op = "neq"; break; + case CEXPR_DOM: op = "dom"; break; + case CEXPR_DOMBY: op = "domby"; break; + case CEXPR_INCOMP: op = "incomp"; break; + default: + sepol_log_err("Unknown constraint operator: %i", curr->op); + goto exit; + } + + switch (curr->attr) { + case CEXPR_USER: attr1 ="u1"; attr2 ="u2"; break; + case CEXPR_USER | CEXPR_TARGET: attr1 ="u2"; attr2 =""; break; + case CEXPR_USER | CEXPR_XTARGET: attr1 ="u3"; attr2 =""; break; + case CEXPR_ROLE: attr1 ="r1"; attr2 ="r2"; break; + case CEXPR_ROLE | CEXPR_TARGET: attr1 ="r2"; attr2 =""; break; + case CEXPR_ROLE | CEXPR_XTARGET: attr1 ="r3"; attr2 =""; break; + case CEXPR_TYPE: attr1 ="t1"; attr2 ="t2"; break; + case CEXPR_TYPE | CEXPR_TARGET: attr1 ="t2"; attr2 =""; break; + case CEXPR_TYPE | CEXPR_XTARGET: attr1 ="t3"; attr2 =""; break; + case CEXPR_L1L2: attr1 ="l1"; attr2 ="l2"; break; + case CEXPR_L1H2: attr1 ="l1"; attr2 ="h2"; break; + case CEXPR_H1L2: attr1 ="h1"; attr2 ="l2"; break; + case CEXPR_H1H2: attr1 ="h1"; attr2 ="h2"; break; + case CEXPR_L1H1: attr1 ="l1"; attr2 ="h1"; break; + case CEXPR_L2H2: attr1 ="l2"; attr2 ="h2"; break; + default: + sepol_log_err("Unknown constraint attribute: %i", + curr->attr); + goto exit; + } + + if (curr->attr >= CEXPR_XTARGET) { + *use_mls = 1; + } + + if (curr->expr_type == CEXPR_ATTR) { + new_val = create_str("(%s %s %s)", 3, op, attr1, attr2); + } else { + char *names = NULL; + if (curr->attr & CEXPR_TYPE) { + struct type_set *ts = curr->type_names; + names = ebitmap_to_str(&ts->types, pdb->p_type_val_to_name, 1); + } else if (curr->attr & CEXPR_USER) { + names = ebitmap_to_str(&curr->names, pdb->p_user_val_to_name, 1); + } else if (curr->attr & CEXPR_ROLE) { + names = ebitmap_to_str(&curr->names, pdb->p_role_val_to_name, 1); + } + if (!names) { + names = strdup("NO_IDENTIFIER"); + if (!names) { + sepol_log_err("Out of memory"); + goto exit; + } + } + if (strchr(names, ' ')) { + new_val = create_str("(%s %s (%s))", 3, op, attr1, names); + } else { + new_val = create_str("(%s %s %s)", 3, op, attr1, names); + } + free(names); + } + } else { + uint32_t num_params; + char *val1 = NULL; + char *val2 = NULL; + + switch (curr->expr_type) { + case CEXPR_NOT: op = "not"; num_params = 1; break; + case CEXPR_AND: op = "and"; num_params = 2; break; + case CEXPR_OR: op = "or"; num_params = 2; break; + default: + sepol_log_err("Unknown constraint expression type: %i", + curr->expr_type); + goto exit; + } + + if (num_params == 2) { + val2 = strs_stack_pop(stack); + if (!val2) { + sepol_log_err("Invalid constraint expression"); + goto exit; + } + } + val1 = strs_stack_pop(stack); + if (!val1) { + sepol_log_err("Invalid constraint expression"); + goto exit; + } + + if (num_params == 2) { + new_val = create_str("(%s %s %s)", 3, op, val1, val2); + free(val2); + } else { + new_val = create_str("(%s %s)", 2, op, val1); + } + free(val1); + } + if (!new_val) { + goto exit; + } + rc = strs_stack_push(stack, new_val); + if (rc != 0) { + sepol_log_err("Out of memory"); + goto exit; + } + } + + new_val = strs_stack_pop(stack); + if (!new_val || !strs_stack_empty(stack)) { + sepol_log_err("Invalid constraint expression"); + goto exit; + } + + str = new_val; + + strs_stack_destroy(&stack); + + return str; + +exit: + if (stack) { + while ((new_val = strs_stack_pop(stack)) != NULL) { + free(new_val); + } + strs_stack_destroy(&stack); + } + + return NULL; +} + +static int class_constraint_rules_to_strs(struct policydb *pdb, char *classkey, + class_datum_t *class, + struct constraint_node *constraint_rules, + struct strs *mls_list, + struct strs *non_mls_list) +{ + int rc = 0; + struct constraint_node *curr; + char *expr = NULL; + int is_mls; + char *perms; + const char *key_word; + struct strs *strs; + + for (curr = constraint_rules; curr != NULL; curr = curr->next) { + if (curr->permissions == 0) { + continue; + } + expr = constraint_expr_to_str(pdb, curr->expr, &is_mls); + if (!expr) { + rc = -1; + goto exit; + } + + perms = sepol_av_to_string(pdb, class->s.value, curr->permissions); + + if (is_mls) { + key_word = "mlsconstrain"; + strs = mls_list; + } else { + key_word = "constrain"; + strs = non_mls_list; + } + + rc = strs_create_and_add(strs, "(%s (%s (%s)) %s)", 4, key_word, classkey, perms+1, expr); + free(expr); + if (rc != 0) { + goto exit; + } + } + + return 0; +exit: + sepol_log_err("Error gathering constraint rules\n"); + return rc; +} + +static int class_validatetrans_rules_to_strs(struct policydb *pdb, char *classkey, + struct constraint_node *validatetrans_rules, + struct strs *mls_list, + struct strs *non_mls_list) +{ + struct constraint_node *curr; + char *expr = NULL; + int is_mls; + const char *key_word; + struct strs *strs; + int rc = 0; + + for (curr = validatetrans_rules; curr != NULL; curr = curr->next) { + expr = constraint_expr_to_str(pdb, curr->expr, &is_mls); + if (!expr) { + rc = -1; + goto exit; + } + + if (is_mls) { + key_word = "mlsvalidatetrans"; + strs = mls_list; + } else { + key_word = "validatetrans"; + strs = non_mls_list; + } + + rc = strs_create_and_add(strs, "(%s %s %s)", 3, key_word, classkey, expr); + free(expr); + if (rc != 0) { + goto exit; + } + } + +exit: + return rc; +} + +static int constraint_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, struct strs *non_mls_strs) +{ + class_datum_t *class; + char *name; + unsigned i; + int rc = 0; + + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->constraints) { + name = pdb->p_class_val_to_name[i]; + rc = class_constraint_rules_to_strs(pdb, name, class, class->constraints, mls_strs, non_mls_strs); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(mls_strs); + strs_sort(non_mls_strs); + +exit: + return rc; +} + +static int validatetrans_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, struct strs *non_mls_strs) +{ + class_datum_t *class; + char *name; + unsigned i; + int rc = 0; + + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->validatetrans) { + name = pdb->p_class_val_to_name[i]; + rc = class_validatetrans_rules_to_strs(pdb, name, class->validatetrans, mls_strs, non_mls_strs); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(mls_strs); + strs_sort(non_mls_strs); + +exit: + return rc; +} + +static int write_handle_unknown_to_cil(FILE *out, struct policydb *pdb) +{ + const char *action; + + switch (pdb->handle_unknown) { + case SEPOL_DENY_UNKNOWN: + action = "deny"; + break; + case SEPOL_REJECT_UNKNOWN: + action = "reject"; + break; + case SEPOL_ALLOW_UNKNOWN: + action = "allow"; + break; + default: + sepol_log_err("Unknown value for handle-unknown: %i", pdb->handle_unknown); + return -1; + } + + sepol_printf(out, "(handleunknown %s)\n", action); + + return 0; +} + +static char *class_or_common_perms_to_str(symtab_t *permtab) +{ + struct strs *strs; + char *perms = NULL; + int rc; + + rc = strs_init(&strs, permtab->nprim); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(permtab->table, hashtab_ordered_to_strs, strs); + if (rc != 0) { + goto exit; + } + + if (strs_num_items(strs) > 0) { + perms = strs_to_str(strs); + } + +exit: + strs_destroy(&strs); + + return perms; +} + +static int write_class_decl_rules_to_cil(FILE *out, struct policydb *pdb) +{ + class_datum_t *class; + common_datum_t *common; + int *used; + char *name, *perms; + unsigned i; + int rc = 0; + + /* class */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + name = pdb->p_class_val_to_name[i]; + perms = class_or_common_perms_to_str(&class->permissions); + if (perms) { + sepol_printf(out, "(class %s (%s))\n", name, perms); + free(perms); + } else { + sepol_printf(out, "(class %s ())\n", name); + } + } + + /* classorder */ + sepol_printf(out, "(classorder ("); + name = NULL; + for (i=0; i < pdb->p_classes.nprim; i++) { + if (name) { + sepol_printf(out, "%s ", name); + } + name = pdb->p_class_val_to_name[i]; + } + if (name) { + sepol_printf(out, "%s", name); + } + sepol_printf(out, "))\n"); + + /* classcommon */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + name = pdb->p_class_val_to_name[i]; + if (class->comkey != NULL) { + sepol_printf(out, "(classcommon %s %s)\n", name, class->comkey); + } + } + + /* common */ + used = calloc(pdb->p_commons.nprim, sizeof(*used)); + if (!used) { + sepol_log_err("Out of memory"); + rc = -1; + goto exit; + } + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + name = class->comkey; + if (name != NULL) { + common = hashtab_search(pdb->p_commons.table, name); + if (!common) { + rc = -1; + free(used); + goto exit; + } + /* Only write common rule once */ + if (!used[common->s.value-1]) { + perms = class_or_common_perms_to_str(&common->permissions); + if (!perms) { + rc = -1; + free(perms); + free(used); + goto exit; + } + + sepol_printf(out, "(common %s (%s))\n", name, perms); + free(perms); + used[common->s.value-1] = 1; + } + } + } + free(used); + +exit: + if (rc != 0) { + sepol_log_err("Error writing class rules to CIL\n"); + } + + return rc; +} + +static int write_sids_to_cil(FILE *out, const char *const *sid_to_str, + unsigned num_sids, struct ocontext *isids) +{ + struct ocontext *isid; + struct strs *strs; + char *sid; + char *prev; + char unknown[18]; + unsigned i; + int rc; + + rc = strs_init(&strs, num_sids+1); + if (rc != 0) { + goto exit; + } + + for (isid = isids; isid != NULL; isid = isid->next) { + i = isid->sid[0]; + if (i < num_sids) { + sid = (char *)sid_to_str[i]; + } else { + snprintf(unknown, 18, "%s%u", "UNKNOWN", i); + sid = strdup(unknown); + if (!sid) { + sepol_log_err("Out of memory"); + rc = -1; + goto exit; + } + } + rc = strs_add_at_index(strs, sid, i); + if (rc != 0) { + goto exit; + } + } + + for (i=0; itarget_platform == SEPOL_TARGET_SELINUX) { + rc = write_sids_to_cil(out, selinux_sid_to_str, SELINUX_SID_SZ, + pdb->ocontexts[0]); + } else if (pdb->target_platform == SEPOL_TARGET_XEN) { + rc = write_sids_to_cil(out, xen_sid_to_str, XEN_SID_SZ, + pdb->ocontexts[0]); + } else { + sepol_log_err("Unknown target platform: %i", pdb->target_platform); + rc = -1; + } + + return rc; +} + +static int write_default_user_to_cil(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_user) { + case DEFAULT_SOURCE: + dft = "source"; + break; + case DEFAULT_TARGET: + dft = "target"; + break; + default: + sepol_log_err("Unknown default role value: %i", class->default_user); + return -1; + } + sepol_printf(out, "(defaultuser %s %s)\n", class_name, dft); + + return 0; +} + +static int write_default_role_to_cil(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_role) { + case DEFAULT_SOURCE: + dft = "source"; + break; + case DEFAULT_TARGET: + dft = "target"; + break; + default: + sepol_log_err("Unknown default role value: %i", class->default_role); + return -1; + } + sepol_printf(out, "(defaultrole %s %s)\n", class_name, dft); + + return 0; +} + +static int write_default_type_to_cil(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_type) { + case DEFAULT_SOURCE: + dft = "source"; + break; + case DEFAULT_TARGET: + dft = "target"; + break; + default: + sepol_log_err("Unknown default type value: %i", class->default_type); + return -1; + } + sepol_printf(out, "(defaulttype %s %s)\n", class_name, dft); + + return 0; +} + +static int write_default_range_to_cil(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_range) { + case DEFAULT_SOURCE_LOW: + dft = "source low"; + break; + case DEFAULT_SOURCE_HIGH: + dft = "source high"; + break; + case DEFAULT_SOURCE_LOW_HIGH: + dft = "source low-high"; + break; + case DEFAULT_TARGET_LOW: + dft = "target low"; + break; + case DEFAULT_TARGET_HIGH: + dft = "target high"; + break; + case DEFAULT_TARGET_LOW_HIGH: + dft = "target low-high"; + break; + case DEFAULT_GLBLUB: + dft = "glblub"; + break; + default: + sepol_log_err("Unknown default type value: %i", class->default_range); + return -1; + } + sepol_printf(out, "(defaultrange %s %s)\n", class_name, dft); + + return 0; +} + +static int write_default_rules_to_cil(FILE *out, struct policydb *pdb) +{ + class_datum_t *class; + unsigned i; + int rc = 0; + + /* default_user */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_user != 0) { + rc = write_default_user_to_cil(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + + /* default_role */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_role != 0) { + rc = write_default_role_to_cil(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + + /* default_type */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_type != 0) { + rc = write_default_type_to_cil(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + + if (!pdb->mls) { + return 0; + } + + /* default_range */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_range) { + rc = write_default_range_to_cil(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing default rules to CIL\n"); + } + + return rc; +} + +static void write_default_mls_level(FILE *out) +{ + sepol_printf(out, "(sensitivity s0)\n"); + sepol_printf(out, "(sensitivityorder (s0))\n"); + sepol_printf(out, "(level %s (s0))\n", DEFAULT_LEVEL); +} + +static int map_count_sensitivity_aliases(__attribute__((unused)) char *key, void *data, void *args) +{ + level_datum_t *sens = data; + unsigned *count = args; + + if (sens->isalias) + (*count)++; + + return SEPOL_OK; +} + +static int map_sensitivity_aliases_to_strs(char *key, void *data, void *args) +{ + level_datum_t *sens = data; + struct strs *strs = args; + int rc = 0; + + if (sens->isalias) { + rc = strs_add(strs, key); + } + + return rc; +} + +static int write_sensitivity_rules_to_cil(FILE *out, struct policydb *pdb) +{ + level_datum_t *level; + char *prev, *name, *actual; + struct strs *strs = NULL; + unsigned i, num = 0; + int rc = 0; + + /* sensitivities */ + for (i=0; i < pdb->p_levels.nprim; i++) { + name = pdb->p_sens_val_to_name[i]; + sepol_printf(out, "(sensitivity %s)\n", name); + } + + /* sensitivityorder */ + sepol_printf(out, "(sensitivityorder ("); + prev = NULL; + for (i=0; i < pdb->p_levels.nprim; i++) { + name = pdb->p_sens_val_to_name[i]; + if (prev) { + sepol_printf(out, "%s ", prev); + } + prev = name; + } + if (prev) { + sepol_printf(out, "%s", prev); + } + sepol_printf(out, "))\n"); + + rc = ksu_hashtab_map(pdb->p_levels.table, map_count_sensitivity_aliases, &num); + if (rc != 0) { + goto exit; + } + + if (num == 0) { + /* No aliases, so skip sensitivity alias rules */ + rc = 0; + goto exit; + } + + rc = strs_init(&strs, num); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_levels.table, map_sensitivity_aliases_to_strs, strs); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + + /* sensitivity aliases */ + for (i=0; i < num; i++) { + name = strs_read_at_index(strs, i); + sepol_printf(out, "(sensitivityalias %s)\n", name); + } + + /* sensitivity aliases to actual */ + for (i=0; i < num; i++) { + name = strs_read_at_index(strs, i); + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + actual = pdb->p_sens_val_to_name[level->level->sens - 1]; + sepol_printf(out, "(sensitivityaliasactual %s %s)\n", name, actual); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing sensitivity rules to CIL\n"); + } + + return rc; +} + +static int map_count_category_aliases(__attribute__((unused)) char *key, void *data, void *args) +{ + cat_datum_t *cat = data; + unsigned *count = args; + + if (cat->isalias) + (*count)++; + + return SEPOL_OK; +} + +static int map_category_aliases_to_strs(char *key, void *data, void *args) +{ + cat_datum_t *cat = data; + struct strs *strs = args; + int rc = 0; + + if (cat->isalias) { + rc = strs_add(strs, key); + } + + return rc; +} + +static int write_category_rules_to_cil(FILE *out, struct policydb *pdb) +{ + cat_datum_t *cat; + char *prev, *name, *actual; + struct strs *strs = NULL; + unsigned i, num = 0; + int rc = 0; + + /* categories */ + for (i=0; i < pdb->p_cats.nprim; i++) { + name = pdb->p_cat_val_to_name[i]; + sepol_printf(out, "(category %s)\n", name); + } + + /* categoryorder */ + sepol_printf(out, "(categoryorder ("); + prev = NULL; + for (i=0; i < pdb->p_cats.nprim; i++) { + name = pdb->p_cat_val_to_name[i]; + if (prev) { + sepol_printf(out, "%s ", prev); + } + prev = name; + } + if (prev) { + sepol_printf(out, "%s", prev); + } + sepol_printf(out, "))\n"); + + rc = ksu_hashtab_map(pdb->p_cats.table, map_count_category_aliases, &num); + if (rc != 0) { + goto exit; + } + + if (num == 0) { + /* No aliases, so skip category alias rules */ + rc = 0; + goto exit; + } + + rc = strs_init(&strs, num); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_cats.table, map_category_aliases_to_strs, strs); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + + /* category aliases */ + for (i=0; i < num; i++) { + name = strs_read_at_index(strs, i); + sepol_printf(out, "(categoryalias %s)\n", name); + } + + /* category aliases to actual */ + for (i=0; i < num; i++) { + name = strs_read_at_index(strs, i); + cat = hashtab_search(pdb->p_cats.table, name); + if (!cat) { + rc = -1; + goto exit; + } + actual = pdb->p_cat_val_to_name[cat->s.value - 1]; + sepol_printf(out, "(categoryaliasactual %s %s)\n", name, actual); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing category rules to CIL\n"); + } + + return rc; +} + +static size_t cats_ebitmap_len(struct ebitmap *cats, char **val_to_name) +{ + struct ebitmap_node *node; + uint32_t i, start, range; + size_t len = 0; + + range = 0; + ebitmap_for_each_positive_bit(cats, node, i) { + if (range == 0) + start = i; + + range++; + + if (ksu_ebitmap_get_bit(cats, i+1)) + continue; + + len += strlen(val_to_name[start]); + if (range > 2) { + len += strlen(val_to_name[i-1]) + strlen("(range ) "); + } else if (range == 2) { + len += strlen(val_to_name[i-1]) + 2; + } else if (range == 1) { + len += 1; + } + + range = 0; + } + + if (len > 0) { + len += 2; /* For '(' and ')'. '\0' overwrites last ' ' */ + } + + return len; +} + +static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name) +{ + struct ebitmap_node *node; + uint32_t i, start, range; + char *catsbuf = NULL, *p; + int len, remaining; + + remaining = (int)cats_ebitmap_len(cats, val_to_name); + if (remaining == 0) { + goto exit; + } + catsbuf = malloc(remaining); + if (!catsbuf) { + goto exit; + } + + p = catsbuf; + + *p++ = '('; + remaining--; + + range = 0; + ebitmap_for_each_positive_bit(cats, node, i) { + if (range == 0) + start = i; + + range++; + + if (ksu_ebitmap_get_bit(cats, i+1)) + continue; + + if (range > 1) { + if (range == 2) { + len = snprintf(p, remaining, "%s %s ", + val_to_name[start], + val_to_name[i]); + } else { + len = snprintf(p, remaining, "(range %s %s) ", + val_to_name[start], + val_to_name[i]); + } + } else { + len = snprintf(p, remaining, "%s ", val_to_name[start]); + } + if (len < 0 || len >= remaining) { + goto exit; + } + p += len; + remaining -= len; + + range = 0; + } + + *(p-1) = ')'; /* Remove trailing ' ' */ + *p = '\0'; + + return catsbuf; + +exit: + free(catsbuf); + return NULL; +} + +static int write_sensitivitycategory_rules_to_cil(FILE *out, struct policydb *pdb) +{ + level_datum_t *level; + char *name, *cats; + unsigned i; + int rc = 0; + + /* sensitivities */ + for (i=0; i < pdb->p_levels.nprim; i++) { + name = pdb->p_sens_val_to_name[i]; + if (!name) continue; + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + if (level->isalias) continue; + + if (!ebitmap_is_empty(&level->level->cat)) { + cats = cats_ebitmap_to_str(&level->level->cat, pdb->p_cat_val_to_name); + sepol_printf(out, "(sensitivitycategory %s %s)\n", name, cats); + free(cats); + } + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing sensitivitycategory rules to CIL\n"); + } + + return rc; +} + +static int write_mls_rules_to_cil(FILE *out, struct policydb *pdb) +{ + int rc = 0; + + if (!pdb->mls) { + sepol_printf(out, "(mls false)\n"); + /* CIL requires MLS, even if the kernel binary won't have it */ + write_default_mls_level(out); + return 0; + } + + sepol_printf(out, "(mls true)\n"); + + rc = write_sensitivity_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_category_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_sensitivitycategory_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing mls rules to CIL\n"); + } + + return rc; +} + +static int write_polcap_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct strs *strs; + struct ebitmap_node *node; + const char *name; + uint32_t i; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) { + name = sepol_polcap_getname(i); + if (name == NULL) { + sepol_log_err("Unknown policy capability id: %i", i); + rc = -1; + goto exit; + } + + rc = strs_create_and_add(strs, "(policycap %s)", 1, name); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing polcap rules to CIL\n"); + } + + return rc; +} + +static int write_type_attributes_to_cil(FILE *out, struct policydb *pdb) +{ + type_datum_t *type; + char *name; + struct strs *strs; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type = pdb->type_val_to_struct[i]; + if (type && type->flavor == TYPE_ATTRIB) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i = 0; i < num; i++) { + name = strs_read_at_index(strs, i); + if (!name) { + rc = -1; + goto exit; + } + sepol_printf(out, "(typeattribute %s)\n", name); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing typeattribute rules to CIL\n"); + } + + return rc; +} + +static int write_role_attributes_to_cil(FILE *out, struct policydb *pdb) +{ + role_datum_t *role; + char *name; + struct strs *strs; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_roles.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_roles.nprim; i++) { + role = pdb->role_val_to_struct[i]; + if (role && role->flavor == ROLE_ATTRIB) { + rc = strs_add(strs, pdb->p_role_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; istate ? "true" : "false"; + + return strs_create_and_add(strs, "(boolean %s %s)", 2, key, value); +} + +static int write_boolean_decl_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_bools.table, map_boolean_to_strs, strs); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing boolean declarations to CIL\n"); + } + + return rc; +} + +static int write_type_decl_rules_to_cil(FILE *out, struct policydb *pdb) +{ + type_datum_t *type; + struct strs *strs; + char *name; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type = pdb->type_val_to_struct[i]; + if (type && type->flavor == TYPE_TYPE && type->primary) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; iprimary == 0 && datum->flavor == TYPE_TYPE) + (*count)++; + + return SEPOL_OK; +} + +static int map_type_aliases_to_strs(char *key, void *data, void *args) +{ + type_datum_t *datum = data; + struct strs *strs = args; + int rc = 0; + + if (datum->primary == 0 && datum->flavor == TYPE_TYPE) + rc = strs_add(strs, key); + + return rc; +} + +static int write_type_alias_rules_to_cil(FILE *out, struct policydb *pdb) +{ + type_datum_t *alias; + struct strs *strs; + char *name; + char *type; + unsigned i, num = 0; + int rc = 0; + + rc = ksu_hashtab_map(pdb->p_types.table, map_count_type_aliases, &num); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&strs, num); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_types.table, map_type_aliases_to_strs, strs); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + + for (i=0; ip_types.table, name); + if (!alias) { + rc = -1; + goto exit; + } + type = pdb->p_type_val_to_name[alias->s.value - 1]; + sepol_printf(out, "(typealiasactual %s %s)\n", name, type); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing type alias rules to CIL\n"); + } + + return rc; +} + +static int write_type_bounds_rules_to_cil(FILE *out, struct policydb *pdb) +{ + type_datum_t *type; + struct strs *strs; + char *parent; + char *child; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type = pdb->type_val_to_struct[i]; + if (type && type->flavor == TYPE_TYPE) { + if (type->bounds > 0) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; ip_types.table, child); + if (!type) { + rc = -1; + goto exit; + } + parent = pdb->p_type_val_to_name[type->bounds - 1]; + sepol_printf(out, "(typebounds %s %s)\n", parent, child); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing type bounds rules to CIL\n"); + } + + return rc; +} + +static int write_type_attribute_sets_to_cil(FILE *out, struct policydb *pdb) +{ + type_datum_t *attr; + struct strs *strs; + ebitmap_t *typemap; + char *name, *types; + unsigned i; + int rc; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + attr = pdb->type_val_to_struct[i]; + if (!attr || attr->flavor != TYPE_ATTRIB) continue; + name = pdb->p_type_val_to_name[i]; + typemap = &pdb->attr_type_map[i]; + if (ebitmap_is_empty(typemap)) continue; + types = ebitmap_to_str(typemap, pdb->p_type_val_to_name, 1); + if (!types) { + rc = -1; + goto exit; + } + + rc = strs_create_and_add(strs, "(typeattributeset %s (%s))", + 2, name, types); + free(types); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing typeattributeset rules to CIL\n"); + } + + return rc; +} + +static int write_type_permissive_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct strs *strs; + char *name; + struct ebitmap_node *node; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + ebitmap_for_each_positive_bit(&pdb->permissive_map, node, i) { + rc = strs_add(strs, pdb->p_type_val_to_name[i-1]); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; ispecified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) { + return NULL; + } + + for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { + len = 0; + + if (!xperm_test(bit, xperms->perms)) + continue; + + if (in_range && next_bit_in_range(bit, xperms->perms)) { + /* continue until high value found */ + continue; + } else if (next_bit_in_range(bit, xperms->perms)) { + /* low value */ + low_bit = bit; + in_range = 1; + continue; + } + + if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { + value = xperms->driver<<8 | bit; + if (in_range) { + low_value = xperms->driver<<8 | low_bit; + len = snprintf(p, remaining, " (range 0x%hx 0x%hx)", low_value, value); + in_range = 0; + } else { + len = snprintf(p, remaining, " 0x%hx", value); + } + } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { + value = bit << 8; + if (in_range) { + low_value = low_bit << 8; + len = snprintf(p, remaining, " (range 0x%hx 0x%hx)", low_value, (uint16_t) (value|0xff)); + in_range = 0; + } else { + len = snprintf(p, remaining, " (range 0x%hx 0x%hx)", value, (uint16_t) (value|0xff)); + } + + } + if (len < 0 || len >= remaining) { + return NULL; + } + p += len; + remaining -= len; + } + + if (remaining < 2) { + return NULL; + } + + xpermsbuf[0] = '('; + *p++ = ')'; + *p = '\0'; + + return xpermsbuf; +} + +static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_datum_t *datum) +{ + uint32_t data = datum->data; + type_datum_t *type; + const char *flavor, *tgt; + char *src, *class, *perms, *new; + char *rule = NULL; + + switch (0xFFF & key->specified) { + case AVTAB_ALLOWED: + flavor = "allow"; + break; + case AVTAB_AUDITALLOW: + flavor = "auditallow"; + break; + case AVTAB_AUDITDENY: + flavor = "dontaudit"; + data = ~data; + break; + case AVTAB_XPERMS_ALLOWED: + flavor = "allowx"; + break; + case AVTAB_XPERMS_AUDITALLOW: + flavor = "auditallowx"; + break; + case AVTAB_XPERMS_DONTAUDIT: + flavor = "dontauditx"; + break; + case AVTAB_TRANSITION: + flavor = "typetransition"; + break; + case AVTAB_MEMBER: + flavor = "typemember"; + break; + case AVTAB_CHANGE: + flavor = "typechange"; + break; + default: + sepol_log_err("Unknown avtab type: %i", key->specified); + goto exit; + } + + src = pdb->p_type_val_to_name[key->source_type - 1]; + tgt = pdb->p_type_val_to_name[key->target_type - 1]; + if (key->source_type == key->target_type && !(key->specified & AVTAB_TYPE)) { + type = pdb->type_val_to_struct[key->source_type - 1]; + if (type->flavor != TYPE_ATTRIB) { + tgt = "self"; + } + } + class = pdb->p_class_val_to_name[key->target_class - 1]; + + if (key->specified & AVTAB_AV) { + perms = sepol_av_to_string(pdb, key->target_class, data); + if (perms == NULL) { + sepol_log_err("Failed to generate permission string"); + goto exit; + } + rule = create_str("(%s %s %s (%s (%s)))", 5, + flavor, src, tgt, class, perms+1); + } else if (key->specified & AVTAB_XPERMS) { + perms = xperms_to_str(datum->xperms); + if (perms == NULL) { + sepol_log_err("Failed to generate extended permission string"); + goto exit; + } + + rule = create_str("(%s %s %s (%s %s (%s)))", 6, + flavor, src, tgt, "ioctl", class, perms); + } else { + new = pdb->p_type_val_to_name[data - 1]; + + rule = create_str("(%s %s %s %s %s)", 5, flavor, src, tgt, class, new); + } + + if (!rule) { + goto exit; + } + + return rule; + +exit: + return NULL; +} + +struct map_avtab_args { + struct policydb *pdb; + uint32_t flavor; + struct strs *strs; +}; + +static int map_avtab_write_helper(avtab_key_t *key, avtab_datum_t *datum, void *args) +{ + struct map_avtab_args *map_args = args; + uint32_t flavor = map_args->flavor; + struct policydb *pdb = map_args->pdb; + struct strs *strs = map_args->strs; + char *rule; + int rc = 0; + + if (key->specified & flavor) { + rule = avtab_node_to_str(pdb, key, datum); + if (!rule) { + rc = -1; + goto exit; + } + rc = strs_add(strs, rule); + if (rc != 0) { + free(rule); + goto exit; + } + } + +exit: + return rc; +} + +static int write_avtab_flavor_to_cil(FILE *out, struct policydb *pdb, uint32_t flavor, int indent) +{ + struct map_avtab_args args; + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 1000); + if (rc != 0) { + goto exit; + } + + args.pdb = pdb; + args.flavor = flavor; + args.strs = strs; + + rc = avtab_map(&pdb->te_avtab, map_avtab_write_helper, &args); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each_indented(strs, out, indent); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + return rc; +} + +static int write_avtab_to_cil(FILE *out, struct policydb *pdb, int indent) +{ + unsigned i; + int rc = 0; + + for (i = 0; i < AVTAB_FLAVORS_SZ; i++) { + rc = write_avtab_flavor_to_cil(out, pdb, avtab_flavors[i], indent); + if (rc != 0) { + goto exit; + } + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing avtab rules to CIL\n"); + } + + return rc; +} + +struct map_filename_trans_args { + struct policydb *pdb; + struct strs *strs; +}; + +static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg) +{ + filename_trans_key_t *ft = (filename_trans_key_t *)key; + filename_trans_datum_t *datum = data; + struct map_filename_trans_args *map_args = arg; + struct policydb *pdb = map_args->pdb; + struct strs *strs = map_args->strs; + char *src, *tgt, *class, *filename, *new; + struct ebitmap_node *node; + uint32_t bit; + int rc; + + tgt = pdb->p_type_val_to_name[ft->ttype - 1]; + class = pdb->p_class_val_to_name[ft->tclass - 1]; + filename = ft->name; + do { + new = pdb->p_type_val_to_name[datum->otype - 1]; + + ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { + src = pdb->p_type_val_to_name[bit]; + rc = strs_create_and_add(strs, + "(typetransition %s %s %s %s %s)", + 5, src, tgt, class, filename, new); + if (rc) + return rc; + } + + datum = datum->next; + } while (datum); + + return 0; +} + +static int write_filename_trans_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct map_filename_trans_args args; + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 100); + if (rc != 0) { + goto exit; + } + + args.pdb = pdb; + args.strs = strs; + + rc = ksu_hashtab_map(pdb->filename_trans, map_filename_trans_to_str, &args); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing filename typetransition rules to CIL\n"); + } + + return rc; +} + +static char *level_to_str(struct policydb *pdb, struct mls_level *level) +{ + ebitmap_t *cats = &level->cat; + char *level_str = NULL; + char *sens_str = pdb->p_sens_val_to_name[level->sens - 1]; + char *cats_str; + + if (!ebitmap_is_empty(cats)) { + cats_str = cats_ebitmap_to_str(cats, pdb->p_cat_val_to_name); + level_str = create_str("(%s %s)", 2, sens_str, cats_str); + free(cats_str); + } else { + level_str = create_str("(%s)", 1, sens_str); + } + + return level_str; +} + +static char *range_to_str(struct policydb *pdb, mls_range_t *range) +{ + char *low = NULL; + char *high = NULL; + char *range_str = NULL; + + low = level_to_str(pdb, &range->level[0]); + if (!low) { + goto exit; + } + + high = level_to_str(pdb, &range->level[1]); + if (!high) { + goto exit; + } + + range_str = create_str("(%s %s)", 2, low, high); + +exit: + free(low); + free(high); + + return range_str; +} + +struct map_range_trans_args { + struct policydb *pdb; + struct strs *strs; +}; + +static int map_range_trans_to_str(hashtab_key_t key, void *data, void *arg) +{ + range_trans_t *rt = (range_trans_t *)key; + mls_range_t *mls_range = data; + struct map_range_trans_args *map_args = arg; + struct policydb *pdb = map_args->pdb; + struct strs *strs = map_args->strs; + char *src, *tgt, *class, *range; + int rc; + + src = pdb->p_type_val_to_name[rt->source_type - 1]; + tgt = pdb->p_type_val_to_name[rt->target_type - 1]; + class = pdb->p_class_val_to_name[rt->target_class - 1]; + range = range_to_str(pdb, mls_range); + if (!range) { + rc = -1; + goto exit; + } + + rc = strs_create_and_add(strs, "(rangetransition %s %s %s %s)", 4, + src, tgt, class, range); + free(range); + if (rc != 0) { + goto exit; + } + +exit: + return rc; +} + +static int write_range_trans_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct map_range_trans_args args; + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 100); + if (rc != 0) { + goto exit; + } + + args.pdb = pdb; + args.strs = strs; + + rc = ksu_hashtab_map(pdb->range_tr, map_range_trans_to_str, &args); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing range transition rules to CIL\n"); + } + + return rc; +} + +static int write_cond_av_list_to_cil(FILE *out, struct policydb *pdb, cond_av_list_t *cond_list, int indent) +{ + cond_av_list_t *cond_av; + avtab_ptr_t node; + uint32_t flavor; + avtab_key_t *key; + avtab_datum_t *datum; + struct strs *strs; + char *rule; + unsigned i; + int rc; + + for (i = 0; i < AVTAB_FLAVORS_SZ; i++) { + flavor = avtab_flavors[i]; + rc = strs_init(&strs, 64); + if (rc != 0) { + goto exit; + } + + for (cond_av = cond_list; cond_av != NULL; cond_av = cond_av->next) { + node = cond_av->node; + key = &node->key; + datum = &node->datum; + if (key->specified & flavor) { + rule = avtab_node_to_str(pdb, key, datum); + if (!rule) { + rc = -1; + goto exit; + } + rc = strs_add(strs, rule); + if (rc != 0) { + free(rule); + goto exit; + } + } + } + + strs_sort(strs); + strs_write_each_indented(strs, out, indent); + strs_free_all(strs); + strs_destroy(&strs); + } + + return 0; + +exit: + strs_free_all(strs); + strs_destroy(&strs); + return rc; +} + +struct cond_data { + char *expr; + struct cond_node *cond; +}; + +static int cond_node_cmp(const void *a, const void *b) +{ + const struct cond_data *aa = a; + const struct cond_data *bb = b; + return strcmp(aa->expr, bb->expr); +} + +static int write_cond_nodes_to_cil(FILE *out, struct policydb *pdb) +{ + struct cond_data *cond_data; + char *expr; + struct cond_node *cond; + unsigned i, num = 0; + int rc = 0; + + for (cond = pdb->cond_list; cond != NULL; cond = cond->next) { + num++; + } + + cond_data = calloc(num, sizeof(struct cond_data)); + if (!cond_data) { + rc = -1; + goto exit; + } + + i = 0; + for (cond = pdb->cond_list; cond != NULL; cond = cond->next) { + cond_data[i].cond = cond; + expr = cond_expr_to_str(pdb, cond->expr); + if (!expr) { + num = i; + goto exit; + } + cond_data[i].expr = expr; + i++; + } + + qsort(cond_data, num, sizeof(*cond_data), cond_node_cmp); + + for (i=0; itrue_list != NULL) { + sepol_indent(out, 1); + sepol_printf(out, "(true\n"); + rc = write_cond_av_list_to_cil(out, pdb, cond->true_list, 2); + if (rc != 0) { + goto exit; + } + sepol_indent(out, 1); + sepol_printf(out, ")\n"); + } + + if (cond->false_list != NULL) { + sepol_indent(out, 1); + sepol_printf(out, "(false\n"); + rc = write_cond_av_list_to_cil(out, pdb, cond->false_list, 2); + if (rc != 0) { + goto exit; + } + sepol_indent(out, 1); + sepol_printf(out, ")\n"); + } + sepol_printf(out, ")\n"); + } + +exit: + if (cond_data) { + for (i=0; ip_roles.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_roles.nprim; i++) { + role = pdb->role_val_to_struct[i]; + if (role && role->flavor == ROLE_ROLE) { + rc = strs_add(strs, pdb->p_role_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + + for (i=0; ip_roles.table, child); + if (!role) { + rc = -1; + goto exit; + } + + if (role->bounds > 0) { + parent = pdb->p_role_val_to_name[role->bounds - 1]; + sepol_printf(out, "(rolebounds %s %s)\n", parent, child); + } + } + + for (i=0; ip_roles.table, name); + if (!role) { + rc = -1; + goto exit; + } + types = &role->types.types; + if (types && !ebitmap_is_empty(types)) { + rc = strs_init(&type_strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + rc = ebitmap_to_strs(types, type_strs, pdb->p_type_val_to_name); + if (rc != 0) { + strs_destroy(&type_strs); + goto exit; + } + strs_sort(type_strs); + + num_types = strs_num_items(type_strs); + for (j=0; jp_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type_datum = pdb->type_val_to_struct[i]; + if (type_datum && type_datum->flavor == TYPE_TYPE && type_datum->primary) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + + for (i=0; irole_tr; + struct strs *strs; + char *role, *type, *class, *new; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + while (curr) { + role = pdb->p_role_val_to_name[curr->role - 1]; + type = pdb->p_type_val_to_name[curr->type - 1]; + class = pdb->p_class_val_to_name[curr->tclass - 1]; + new = pdb->p_role_val_to_name[curr->new_role - 1]; + + rc = strs_create_and_add(strs, "(roletransition %s %s %s %s)", 4, + role, type, class, new); + if (rc != 0) { + goto exit; + } + + curr = curr->next; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing role transition rules to CIL\n"); + } + + return rc; +} + +static int write_role_allow_rules_to_cil(FILE *out, struct policydb *pdb) +{ + role_allow_t *curr = pdb->role_allow; + struct strs *strs; + char *role, *new; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + while (curr) { + role = pdb->p_role_val_to_name[curr->role - 1]; + new = pdb->p_role_val_to_name[curr->new_role - 1]; + + rc = strs_create_and_add(strs, "(roleallow %s %s)", 2, role, new); + if (rc != 0) { + goto exit; + } + + curr = curr->next; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing role allow rules to CIL\n"); + } + + return rc; +} + +static int write_user_decl_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct user_datum *user; + struct strs *strs, *role_strs; + char *name, *role, *level, *range; + struct ebitmap *roles; + unsigned i, j, num, num_roles; + int rc = 0; + + rc = strs_init(&strs, pdb->p_users.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_users.nprim; i++) { + if (!pdb->p_user_val_to_name[i]) continue; + rc = strs_add(strs, pdb->p_user_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + + for (i=0; ip_users.table, name); + if (!user) { + rc = -1; + goto exit; + } + + roles = &user->roles.roles; + if (roles && !ebitmap_is_empty(roles)) { + rc = strs_init(&role_strs, pdb->p_roles.nprim); + if (rc != 0) { + goto exit; + } + rc = ebitmap_to_strs(roles, role_strs, pdb->p_role_val_to_name); + if (rc != 0) { + strs_destroy(&role_strs); + goto exit; + } + + rc = strs_add(role_strs, (char *)DEFAULT_OBJECT); + if (rc != 0) { + strs_destroy(&role_strs); + goto exit; + } + + strs_sort(role_strs); + + num_roles = strs_num_items(role_strs); + for (j=0; jp_users.table, name); + if (!user) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(userlevel %s ", name); + + if (pdb->mls) { + level = level_to_str(pdb, &user->exp_dfltlevel); + if (!level) { + rc = -1; + goto exit; + } + sepol_printf(out, "%s", level); + free(level); + } else { + sepol_printf(out, "%s", DEFAULT_LEVEL); + } + sepol_printf(out, ")\n"); + } + + for (i=0; ip_users.table, name); + if (!user) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(userrange %s ", name); + if (pdb->mls) { + range = range_to_str(pdb, &user->exp_range); + if (!range) { + rc = -1; + goto exit; + } + sepol_printf(out, "%s", range); + free(range); + } else { + sepol_printf(out, "(%s %s)", DEFAULT_LEVEL, DEFAULT_LEVEL); + } + sepol_printf(out, ")\n"); + } + +exit: + if (strs) + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing user declarations to CIL\n"); + } + + return rc; +} + +static char *context_to_str(struct policydb *pdb, struct context_struct *con) +{ + char *user, *role, *type, *range; + char *ctx = NULL; + + user = pdb->p_user_val_to_name[con->user - 1]; + role = pdb->p_role_val_to_name[con->role - 1]; + type = pdb->p_type_val_to_name[con->type - 1]; + + if (pdb->mls) { + range = range_to_str(pdb, &con->range); + } else { + range = create_str("(%s %s)", 2, DEFAULT_LEVEL, DEFAULT_LEVEL); + } + if (!range) { + goto exit; + } + + ctx = create_str("(%s %s %s %s)", 4, user, role, type, range); + free(range); + +exit: + return ctx; +} + +static int write_sid_context_rules_to_cil(FILE *out, struct policydb *pdb, const char *const *sid_to_str, unsigned num_sids) +{ + struct ocontext *isid; + struct strs *strs; + char *sid; + char unknown[18]; + char *ctx, *rule; + unsigned i; + int rc = -1; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + for (isid = pdb->ocontexts[0]; isid != NULL; isid = isid->next) { + i = isid->sid[0]; + if (i < num_sids) { + sid = (char *)sid_to_str[i]; + } else { + snprintf(unknown, 18, "%s%u", "UNKNOWN", i); + sid = unknown; + } + + ctx = context_to_str(pdb, &isid->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + rule = create_str("(sidcontext %s %s)", 2, sid, ctx); + free(ctx); + if (!rule) { + rc = -1; + goto exit; + } + + rc = strs_add_at_index(strs, rule, i); + if (rc != 0) { + free(rule); + goto exit; + } + } + + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing sidcontext rules to CIL\n"); + } + + return rc; +} + +static int write_selinux_isid_rules_to_cil(FILE *out, struct policydb *pdb) +{ + return write_sid_context_rules_to_cil(out, pdb, selinux_sid_to_str, + SELINUX_SID_SZ); +} + +static int write_selinux_fsuse_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *fsuse; + const char *behavior; + char *name, *ctx; + int rc = 0; + + for (fsuse = pdb->ocontexts[5]; fsuse != NULL; fsuse = fsuse->next) { + switch (fsuse->v.behavior) { + case SECURITY_FS_USE_XATTR: behavior = "xattr"; break; + case SECURITY_FS_USE_TRANS: behavior = "trans"; break; + case SECURITY_FS_USE_TASK: behavior = "task"; break; + default: + sepol_log_err("Unknown fsuse behavior: %i", fsuse->v.behavior); + rc = -1; + goto exit; + } + + name = fsuse->u.name; + ctx = context_to_str(pdb, &fsuse->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(fsuse %s %s %s)\n", behavior, name, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing fsuse rules to CIL\n"); + } + + return rc; +} + +static int write_genfscon_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct genfs *genfs; + struct ocontext *ocon; + struct strs *strs; + char *fstype, *name, *ctx; + uint32_t sclass; + const char *file_type; + int rc; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) { + for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) { + fstype = genfs->fstype; + name = ocon->u.name; + + sclass = ocon->v.sclass; + file_type = NULL; + if (sclass) { + const char *class_name = pdb->p_class_val_to_name[sclass-1]; + if (strcmp(class_name, "file") == 0) { + file_type = "file"; + } else if (strcmp(class_name, "dir") == 0) { + file_type = "dir"; + } else if (strcmp(class_name, "chr_file") == 0) { + file_type = "char"; + } else if (strcmp(class_name, "blk_file") == 0) { + file_type = "block"; + } else if (strcmp(class_name, "sock_file") == 0) { + file_type = "socket"; + } else if (strcmp(class_name, "fifo_file") == 0) { + file_type = "pipe"; + } else if (strcmp(class_name, "lnk_file") == 0) { + file_type = "symlink"; + } else { + rc = -1; + goto exit; + } + } + + ctx = context_to_str(pdb, &ocon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + if (file_type) { + rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s %s)", 4, + fstype, name, file_type, ctx); + } else { + rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s)", 3, + fstype, name, ctx); + } + free(ctx); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing genfscon rules to CIL\n"); + } + + return rc; +} + +static int write_selinux_port_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *portcon; + const char *protocol; + uint16_t low; + uint16_t high; + char low_high_str[44]; /* 2^64 <= 20 digits so "(low high)" <= 44 chars */ + char *ctx; + int rc = 0; + + for (portcon = pdb->ocontexts[2]; portcon != NULL; portcon = portcon->next) { + switch (portcon->u.port.protocol) { + case IPPROTO_TCP: protocol = "tcp"; break; + case IPPROTO_UDP: protocol = "udp"; break; + case IPPROTO_DCCP: protocol = "dccp"; break; + case IPPROTO_SCTP: protocol = "sctp"; break; + default: + sepol_log_err("Unknown portcon protocol: %i", portcon->u.port.protocol); + rc = -1; + goto exit; + } + + low = portcon->u.port.low_port; + high = portcon->u.port.high_port; + if (low == high) { + rc = snprintf(low_high_str, 44, "%u", low); + } else { + rc = snprintf(low_high_str, 44, "(%u %u)", low, high); + } + if (rc < 0 || rc >= 44) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &portcon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(portcon %s %s %s)\n", protocol, low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing portcon rules to CIL\n"); + } + + return rc; +} + +static int write_selinux_netif_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *netif; + char *name, *ctx1, *ctx2; + int rc = 0; + + for (netif = pdb->ocontexts[3]; netif != NULL; netif = netif->next) { + name = netif->u.name; + ctx1 = context_to_str(pdb, &netif->context[0]); + if (!ctx1) { + rc = -1; + goto exit; + } + ctx2 = context_to_str(pdb, &netif->context[1]); + if (!ctx2) { + free(ctx1); + rc = -1; + goto exit; + } + + sepol_printf(out, "(netifcon %s %s %s)\n", name, ctx1, ctx2); + + free(ctx1); + free(ctx2); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing netifcon rules to CIL\n"); + } + + return rc; +} + +static int write_selinux_node_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *node; + char addr[INET_ADDRSTRLEN]; + char mask[INET_ADDRSTRLEN]; + char *ctx; + int rc = 0; + + for (node = pdb->ocontexts[4]; node != NULL; node = node->next) { + if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon address is invalid: %m"); + rc = -1; + goto exit; + } + + if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon mask is invalid: %m"); + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &node->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(nodecon (%s) (%s) %s)\n", addr, mask, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing nodecon rules to CIL\n"); + } + + return rc; +} + +static int write_selinux_node6_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *node; + char addr[INET6_ADDRSTRLEN]; + char mask[INET6_ADDRSTRLEN]; + char *ctx; + int rc = 0; + + for (node = pdb->ocontexts[6]; node != NULL; node = node->next) { + if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon address is invalid: %m"); + rc = -1; + goto exit; + } + + if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon mask is invalid: %m"); + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &node->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(nodecon (%s) (%s) %s)\n", addr, mask, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing nodecon rules to CIL\n"); + } + + return rc; +} + +static int write_selinux_ibpkey_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *ibpkeycon; + char subnet_prefix_str[INET6_ADDRSTRLEN]; + struct in6_addr subnet_prefix = IN6ADDR_ANY_INIT; + uint16_t low; + uint16_t high; + char low_high_str[44]; /* 2^64 <= 20 digits so "(low high)" <= 44 chars */ + char *ctx; + int rc = 0; + + for (ibpkeycon = pdb->ocontexts[OCON_IBPKEY]; ibpkeycon != NULL; + ibpkeycon = ibpkeycon->next) { + memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix, + sizeof(ibpkeycon->u.ibpkey.subnet_prefix)); + + if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, + subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { + sepol_log_err("ibpkeycon subnet_prefix is invalid: %m"); + rc = -1; + goto exit; + } + + low = ibpkeycon->u.ibpkey.low_pkey; + high = ibpkeycon->u.ibpkey.high_pkey; + if (low == high) { + rc = snprintf(low_high_str, 44, "%u", low); + } else { + rc = snprintf(low_high_str, 44, "(%u %u)", low, high); + } + if (rc < 0 || rc >= 44) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &ibpkeycon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(ibpkeycon %s %s %s)\n", subnet_prefix_str, low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing ibpkeycon rules to CIL\n"); + } + + return rc; +} + +static int write_selinux_ibendport_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *ibendportcon; + char port_str[4]; + char *ctx; + int rc = 0; + + for (ibendportcon = pdb->ocontexts[OCON_IBENDPORT]; + ibendportcon != NULL; ibendportcon = ibendportcon->next) { + rc = snprintf(port_str, 4, "%u", ibendportcon->u.ibendport.port); + if (rc < 0 || rc >= 4) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &ibendportcon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(ibendportcon %s %s %s)\n", + ibendportcon->u.ibendport.dev_name, port_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing ibendportcon rules to CIL\n"); + } + + return rc; +} + +static int write_xen_isid_rules_to_cil(FILE *out, struct policydb *pdb) +{ + return write_sid_context_rules_to_cil(out, pdb, xen_sid_to_str, XEN_SID_SZ); +} + +static int write_xen_pirq_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *pirq; + char pirq_str[21]; /* 2^64-1 <= 20 digits */ + char *ctx; + int rc = 0; + + for (pirq = pdb->ocontexts[1]; pirq != NULL; pirq = pirq->next) { + rc = snprintf(pirq_str, 21, "%i", pirq->u.pirq); + if (rc < 0 || rc >= 21) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &pirq->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(pirqcon %s %s)\n", pirq_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing pirqcon rules to CIL\n"); + } + + return rc; +} + +static int write_xen_ioport_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *ioport; + uint32_t low; + uint32_t high; + char low_high_str[40]; /* 2^64-1 <= 16 digits (hex) so (low high) < 40 chars */ + char *ctx; + int rc = 0; + + for (ioport = pdb->ocontexts[2]; ioport != NULL; ioport = ioport->next) { + low = ioport->u.ioport.low_ioport; + high = ioport->u.ioport.high_ioport; + if (low == high) { + rc = snprintf(low_high_str, 40, "0x%x", low); + } else { + rc = snprintf(low_high_str, 40, "(0x%x 0x%x)", low, high); + } + if (rc < 0 || rc >= 40) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &ioport->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(ioportcon %s %s)\n", low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing ioportcon rules to CIL\n"); + } + + return rc; +} + +static int write_xen_iomem_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *iomem; + uint64_t low; + uint64_t high; + char low_high_str[40]; /* 2^64-1 <= 16 digits (hex) so (low high) < 40 chars */ + char *ctx; + int rc = 0; + + for (iomem = pdb->ocontexts[3]; iomem != NULL; iomem = iomem->next) { + low = iomem->u.iomem.low_iomem; + high = iomem->u.iomem.high_iomem; + if (low == high) { + rc = snprintf(low_high_str, 40, "0x%"PRIx64, low); + } else { + rc = snprintf(low_high_str, 40, "(0x%"PRIx64" 0x%"PRIx64")", low, high); + } + if (rc < 0 || rc >= 40) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &iomem->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(iomemcon %s %s)\n", low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing iomemcon rules to CIL\n"); + } + + return rc; +} + +static int write_xen_pcidevice_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *pcid; + char device_str[20]; /* 2^64-1 <= 16 digits (hex) so (low high) < 19 chars */ + char *ctx; + int rc = 0; + + for (pcid = pdb->ocontexts[4]; pcid != NULL; pcid = pcid->next) { + rc = snprintf(device_str, 20, "0x%lx", (unsigned long)pcid->u.device); + if (rc < 0 || rc >= 20) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &pcid->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(pcidevicecon %s %s)\n", device_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing pcidevicecon rules to CIL\n"); + } + + return rc; +} + +static int write_xen_devicetree_rules_to_cil(FILE *out, struct policydb *pdb) +{ + struct ocontext *dtree; + char *name, *ctx; + int rc = 0; + + for (dtree = pdb->ocontexts[5]; dtree != NULL; dtree = dtree->next) { + name = dtree->u.name; + ctx = context_to_str(pdb, &dtree->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "(devicetreecon \"%s\" %s)\n", name, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing devicetreecon rules to CIL\n"); + } + + return rc; +} + +int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb) +{ + struct strs *mls_constraints = NULL; + struct strs *non_mls_constraints = NULL; + struct strs *mls_validatetrans = NULL; + struct strs *non_mls_validatetrans = NULL; + int rc = 0; + + rc = strs_init(&mls_constraints, 32); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&non_mls_constraints, 32); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&mls_validatetrans, 32); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&non_mls_validatetrans, 32); + if (rc != 0) { + goto exit; + } + + if (pdb == NULL) { + sepol_log_err("No policy"); + rc = -1; + goto exit; + } + + if (pdb->policy_type != SEPOL_POLICY_KERN) { + sepol_log_err("Policy is not a kernel policy"); + rc = -1; + goto exit; + } + + if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { + /* + * For policy versions between 20 and 23, attributes exist in the policy, + * but only in the type_attr_map. This means that there are gaps in both + * the type_val_to_struct and p_type_val_to_name arrays and policy rules + * can refer to those gaps. + */ + sepol_log_err("Writing policy versions between 20 and 23 as CIL is not supported"); + rc = -1; + goto exit; + } + + rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints); + if (rc != 0) { + goto exit; + } + + rc = validatetrans_rules_to_strs(pdb, mls_validatetrans, non_mls_validatetrans); + if (rc != 0) { + goto exit; + } + + rc = write_handle_unknown_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_class_decl_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_sid_decl_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_default_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_mls_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + strs_write_each(mls_constraints, out); + strs_write_each(mls_validatetrans, out); + + rc = write_polcap_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_attributes_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_attributes_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_boolean_decl_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_decl_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_alias_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_bounds_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_attribute_sets_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_permissive_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_avtab_to_cil(out, pdb, 0); + if (rc != 0) { + goto exit; + } + + rc = write_filename_trans_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + if (pdb->mls) { + rc = write_range_trans_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + } + + rc = write_cond_nodes_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_decl_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_transition_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_allow_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_user_decl_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + strs_write_each(non_mls_constraints, out); + strs_write_each(non_mls_validatetrans, out); + + rc = sort_ocontexts(pdb); + if (rc != 0) { + goto exit; + } + + if (pdb->target_platform == SEPOL_TARGET_SELINUX) { + rc = write_selinux_isid_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_fsuse_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_genfscon_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_port_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_netif_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_node_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_node6_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_ibpkey_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_ibendport_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + } else if (pdb->target_platform == SEPOL_TARGET_XEN) { + rc = write_xen_isid_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_pirq_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_ioport_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_iomem_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_pcidevice_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_devicetree_rules_to_cil(out, pdb); + if (rc != 0) { + goto exit; + } + } + +exit: + strs_free_all(mls_constraints); + strs_destroy(&mls_constraints); + strs_free_all(non_mls_constraints); + strs_destroy(&non_mls_constraints); + strs_free_all(mls_validatetrans); + strs_destroy(&mls_validatetrans); + strs_free_all(non_mls_validatetrans); + strs_destroy(&non_mls_validatetrans); + + return rc; +} diff --git a/kernel/libsepol/src/kernel_to_common.c b/kernel/libsepol/src/kernel_to_common.c new file mode 100644 index 00000000..3f787915 --- /dev/null +++ b/kernel/libsepol/src/kernel_to_common.c @@ -0,0 +1,731 @@ +// #include +// #include +// #include +#include +#include +// #include + +// #include +// #include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +#include +#include +#include + +#include "private.h" +#include "kernel_to_common.h" + + +void sepol_log_err(const char *fmt, ...) +{ +#if 0 + va_list argptr; + va_start(argptr, fmt); + if (vfprintf(stderr, fmt, argptr) < 0) { + _exit(EXIT_FAILURE); + } + va_end(argptr); + if (fprintf(stderr, "\n") < 0) { + _exit(EXIT_FAILURE); + } +#endif +} + +void sepol_indent(FILE *out, int indent) +{ +#if 0 + if (fprintf(out, "%*s", indent * 4, "") < 0) { + sepol_log_err("Failed to write to output"); + } +#endif +} + +void sepol_printf(FILE *out, const char *fmt, ...) +{ +#if 0 + va_list argptr; + va_start(argptr, fmt); + if (vfprintf(out, fmt, argptr) < 0) { + sepol_log_err("Failed to write to output"); + } + va_end(argptr); +#endif +} + +__attribute__ ((format(printf, 1, 0))) +static char *create_str_helper(const char *fmt, int num, va_list vargs) +{ + va_list vargs2; + char *str = NULL; + char *s; + size_t len, s_len; + int i, rc; + + va_copy(vargs2, vargs); + + len = strlen(fmt) + 1; /* +1 for '\0' */ + + for (i=0; i 1 ? s_len - 2 : 0; /* -2 for each %s in fmt */ + } + + str = malloc(len); + if (!str) { + sepol_log_err("Out of memory"); + goto exit; + } + + rc = vsnprintf(str, len, fmt, vargs2); + if (rc < 0 || rc >= (int)len) { + goto exit; + } + + va_end(vargs2); + + return str; + +exit: + free(str); + va_end(vargs2); + return NULL; +} + +char *create_str(const char *fmt, int num, ...) +{ + char *str = NULL; + va_list vargs; + + va_start(vargs, num); + str = create_str_helper(fmt, num, vargs); + va_end(vargs); + + return str; +} + +int strs_init(struct strs **strs, size_t size) +{ + struct strs *new; + + if (size == 0) { + size = 1; + } + + *strs = NULL; + + new = malloc(sizeof(struct strs)); + if (!new) { + sepol_log_err("Out of memory"); + return -1; + } + + new->list = calloc(size, sizeof(char *)); + if (!new->list) { + sepol_log_err("Out of memory"); + free(new); + return -1; + } + + new->num = 0; + new->size = size; + + *strs = new; + + return 0; +} + +void strs_destroy(struct strs **strs) +{ + if (!strs || !*strs) { + return; + } + + free((*strs)->list); + (*strs)->list = NULL; + (*strs)->num = 0; + (*strs)->size = 0; + free(*strs); + *strs = NULL; +} + +void strs_free_all(struct strs *strs) +{ + if (!strs) { + return; + } + + while (strs->num > 0) { + strs->num--; + free(strs->list[strs->num]); + } +} + +int strs_add(struct strs *strs, char *s) +{ + if (strs->num + 1 > strs->size) { + char **new; + size_t i = strs->size; + strs->size *= 2; + new = reallocarray(strs->list, strs->size, sizeof(char *)); + if (!new) { + sepol_log_err("Out of memory"); + return -1; + } + strs->list = new; + memset(&strs->list[i], 0, sizeof(char *)*(strs->size-i)); + } + + strs->list[strs->num] = s; + strs->num++; + + return 0; +} + +int strs_create_and_add(struct strs *strs, const char *fmt, int num, ...) +{ + char *str; + va_list vargs; + int rc; + + va_start(vargs, num); + str = create_str_helper(fmt, num, vargs); + va_end(vargs); + + if (!str) { + rc = -1; + goto exit; + } + + rc = strs_add(strs, str); + if (rc != 0) { + free(str); + goto exit; + } + + return 0; + +exit: + return rc; +} + +char *strs_remove_last(struct strs *strs) +{ + if (strs->num == 0) { + return NULL; + } + strs->num--; + return strs->list[strs->num]; +} + +int strs_add_at_index(struct strs *strs, char *s, size_t index) +{ + if (index >= strs->size) { + char **new; + size_t i = strs->size; + while (index >= strs->size) { + strs->size *= 2; + } + new = reallocarray(strs->list, strs->size, sizeof(char *)); + if (!new) { + sepol_log_err("Out of memory"); + return -1; + } + strs->list = new; + memset(&strs->list[i], 0, sizeof(char *)*(strs->size - i)); + } + + strs->list[index] = s; + if (index >= strs->num) { + strs->num = index+1; + } + + return 0; +} + +char *strs_read_at_index(struct strs *strs, size_t index) +{ + if (index >= strs->num) { + return NULL; + } + + return strs->list[index]; +} + +static int strs_cmp(const void *a, const void *b) +{ + char *const *aa = a; + char *const *bb = b; + return strcmp(*aa,*bb); +} + +void strs_sort(struct strs *strs) +{ + if (strs->num == 0) { + return; + } + qsort(strs->list, strs->num, sizeof(char *), strs_cmp); +} + +unsigned strs_num_items(const struct strs *strs) +{ + return strs->num; +} + +size_t strs_len_items(const struct strs *strs) +{ + unsigned i; + size_t len = 0; + + for (i=0; inum; i++) { + if (!strs->list[i]) continue; + len += strlen(strs->list[i]); + } + + return len; +} + +char *strs_to_str(const struct strs *strs) +{ + char *str = NULL; + size_t len = 0; + char *p; + unsigned i; + int rc; + + if (strs->num == 0) { + goto exit; + } + + /* strs->num added because either ' ' or '\0' follows each item */ + len = strs_len_items(strs) + strs->num; + str = malloc(len); + if (!str) { + sepol_log_err("Out of memory"); + goto exit; + } + + p = str; + for (i=0; inum; i++) { + if (!strs->list[i]) continue; + len = strlen(strs->list[i]); + rc = snprintf(p, len+1, "%s", strs->list[i]); + if (rc < 0 || rc > (int)len) { + free(str); + str = NULL; + goto exit; + } + p += len; + if (i < strs->num - 1) { + *p++ = ' '; + } + } + + *p = '\0'; + +exit: + return str; +} + +void strs_write_each(const struct strs *strs, FILE *out) +{ + unsigned i; + + for (i=0; inum; i++) { + if (!strs->list[i]) { + continue; + } + sepol_printf(out, "%s\n",strs->list[i]); + } +} + +void strs_write_each_indented(const struct strs *strs, FILE *out, int indent) +{ + unsigned i; + + for (i=0; inum; i++) { + if (!strs->list[i]) { + continue; + } + sepol_indent(out, indent); + sepol_printf(out, "%s\n",strs->list[i]); + } +} + +int hashtab_ordered_to_strs(char *key, void *data, void *args) +{ + struct strs *strs = (struct strs *)args; + symtab_datum_t *datum = data; + + return strs_add_at_index(strs, key, datum->value-1); +} + +int ebitmap_to_strs(const struct ebitmap *map, struct strs *strs, char **val_to_name) +{ + struct ebitmap_node *node; + uint32_t i; + int rc; + + ebitmap_for_each_positive_bit(map, node, i) { + if (!val_to_name[i]) + continue; + + rc = strs_add(strs, val_to_name[i]); + if (rc != 0) { + return -1; + } + } + + return 0; +} + +char *ebitmap_to_str(const struct ebitmap *map, char **val_to_name, int sort) +{ + struct strs *strs; + char *str = NULL; + int rc; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + rc = ebitmap_to_strs(map, strs, val_to_name); + if (rc != 0) { + goto exit; + } + + if (sort) { + strs_sort(strs); + } + + str = strs_to_str(strs); + +exit: + strs_destroy(&strs); + + return str; +} + +int strs_stack_init(struct strs **stack) +{ + return strs_init(stack, STACK_SIZE); +} + +void strs_stack_destroy(struct strs **stack) +{ + return strs_destroy(stack); +} + +int strs_stack_push(struct strs *stack, char *s) +{ + return strs_add(stack, s); +} + +char *strs_stack_pop(struct strs *stack) +{ + return strs_remove_last(stack); +} + +int strs_stack_empty(const struct strs *stack) +{ + return strs_num_items(stack) == 0; +} + +static int compare_ranges(uint64_t l1, uint64_t h1, uint64_t l2, uint64_t h2) +{ + uint64_t d1, d2; + + d1 = h1-l1; + d2 = h2-l2; + + if (d1 < d2) { + return -1; + } else if (d1 > d2) { + return 1; + } else { + if (l1 < l2) { + return -1; + } else if (l1 > l2) { + return 1; + } + } + + return 0; +} + +static int fsuse_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + if ((*aa)->v.behavior != (*bb)->v.behavior) { + if ((*aa)->v.behavior < (*bb)->v.behavior) { + return -1; + } else { + return 1; + } + } + + return strcmp((*aa)->u.name, (*bb)->u.name); +} + +static int portcon_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + int rc; + + rc = compare_ranges((*aa)->u.port.low_port, (*aa)->u.port.high_port, + (*bb)->u.port.low_port, (*bb)->u.port.high_port); + if (rc == 0) { + if ((*aa)->u.port.protocol < (*bb)->u.port.protocol) { + rc = -1; + } else if ((*aa)->u.port.protocol > (*bb)->u.port.protocol) { + rc = 1; + } + } + + return rc; +} + +static int netif_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + return strcmp((*aa)->u.name, (*bb)->u.name); +} + +static int node_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + int rc; + + rc = memcmp(&(*aa)->u.node.mask, &(*bb)->u.node.mask, sizeof((*aa)->u.node.mask)); + if (rc > 0) { + return -1; + } else if (rc < 0) { + return 1; + } + + return memcmp(&(*aa)->u.node.addr, &(*bb)->u.node.addr, sizeof((*aa)->u.node.addr)); +} + +static int node6_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + int rc; + + rc = memcmp(&(*aa)->u.node6.mask, &(*bb)->u.node6.mask, sizeof((*aa)->u.node6.mask)); + if (rc > 0) { + return -1; + } else if (rc < 0) { + return 1; + } + + return memcmp(&(*aa)->u.node6.addr, &(*bb)->u.node6.addr, sizeof((*aa)->u.node6.addr)); +} + +static int ibpkey_data_cmp(const void *a, const void *b) +{ + int rc; + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + rc = (*aa)->u.ibpkey.subnet_prefix - (*bb)->u.ibpkey.subnet_prefix; + if (rc) + return rc; + + return compare_ranges((*aa)->u.ibpkey.low_pkey, (*aa)->u.ibpkey.high_pkey, + (*bb)->u.ibpkey.low_pkey, (*bb)->u.ibpkey.high_pkey); +} + +static int ibendport_data_cmp(const void *a, const void *b) +{ + int rc; + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + rc = strcmp((*aa)->u.ibendport.dev_name, (*bb)->u.ibendport.dev_name); + if (rc) + return rc; + + return (*aa)->u.ibendport.port - (*bb)->u.ibendport.port; +} + +static int pirq_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + if ((*aa)->u.pirq < (*bb)->u.pirq) { + return -1; + } else if ((*aa)->u.pirq > (*bb)->u.pirq) { + return 1; + } + + return 0; +} + +static int ioport_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + return compare_ranges((*aa)->u.ioport.low_ioport, (*aa)->u.ioport.high_ioport, + (*bb)->u.ioport.low_ioport, (*bb)->u.ioport.high_ioport); +} + +static int iomem_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + return compare_ranges((*aa)->u.iomem.low_iomem, (*aa)->u.iomem.high_iomem, + (*bb)->u.iomem.low_iomem, (*bb)->u.iomem.high_iomem); +} + +static int pcid_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + if ((*aa)->u.device < (*bb)->u.device) { + return -1; + } else if ((*aa)->u.device > (*bb)->u.device) { + return 1; + } + + return 0; +} + +static int dtree_data_cmp(const void *a, const void *b) +{ + struct ocontext *const *aa = a; + struct ocontext *const *bb = b; + + return strcmp((*aa)->u.name, (*bb)->u.name); +} + +static int sort_ocontext_data(struct ocontext **ocons, int (*cmp)(const void *, const void *)) +{ + struct ocontext *ocon; + struct ocontext **data; + unsigned i, num; + + num = 0; + for (ocon = *ocons; ocon != NULL; ocon = ocon->next) { + num++; + } + + if (num == 0) { + return 0; + } + + data = calloc(sizeof(*data), num); + if (!data) { + sepol_log_err("Out of memory\n"); + return -1; + } + + i = 0; + for (ocon = *ocons; ocon != NULL; ocon = ocon->next) { + data[i] = ocon; + i++; + } + + qsort(data, num, sizeof(*data), cmp); + + *ocons = data[0]; + for (i=1; i < num; i++) { + data[i-1]->next = data[i]; + } + data[num-1]->next = NULL; + + free(data); + + return 0; +} + +int sort_ocontexts(struct policydb *pdb) +{ + int rc = 0; + + if (pdb->target_platform == SEPOL_TARGET_SELINUX) { + rc = sort_ocontext_data(&pdb->ocontexts[5], fsuse_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[2], portcon_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[3], netif_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[4], node_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[6], node6_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[OCON_IBPKEY], ibpkey_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[OCON_IBENDPORT], ibendport_data_cmp); + if (rc != 0) { + goto exit; + } + } else if (pdb->target_platform == SEPOL_TARGET_XEN) { + rc = sort_ocontext_data(&pdb->ocontexts[1], pirq_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[2], ioport_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[3], iomem_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[4], pcid_data_cmp); + if (rc != 0) { + goto exit; + } + + rc = sort_ocontext_data(&pdb->ocontexts[5], dtree_data_cmp); + if (rc != 0) { + goto exit; + } + } + +exit: + if (rc != 0) { + sepol_log_err("Error sorting ocontexts\n"); + } + + return rc; +} diff --git a/kernel/libsepol/src/kernel_to_common.h b/kernel/libsepol/src/kernel_to_common.h new file mode 100644 index 00000000..9ec43b08 --- /dev/null +++ b/kernel/libsepol/src/kernel_to_common.h @@ -0,0 +1,121 @@ +// #include +// #include +// #include +#include + +#include +#include + + +#define STACK_SIZE 16 +#define DEFAULT_LEVEL "systemlow" +#define DEFAULT_OBJECT "object_r" + +// initial sid names aren't actually stored in the pp files, need to a have +// a mapping, taken from the linux kernel +static const char * const selinux_sid_to_str[] = { + "null", + "kernel", + "security", + "unlabeled", + "fs", + "file", + "file_labels", + "init", + "any_socket", + "port", + "netif", + "netmsg", + "node", + "igmp_packet", + "icmp_socket", + "tcp_socket", + "sysctl_modprobe", + "sysctl", + "sysctl_fs", + "sysctl_kernel", + "sysctl_net", + "sysctl_net_unix", + "sysctl_vm", + "sysctl_dev", + "kmod", + "policy", + "scmp_packet", + "devnull", +}; + +#define SELINUX_SID_SZ (sizeof(selinux_sid_to_str)/sizeof(selinux_sid_to_str[0])) + +static const char * const xen_sid_to_str[] = { + "null", + "xen", + "dom0", + "domio", + "domxen", + "unlabeled", + "security", + "ioport", + "iomem", + "irq", + "device", + "domU", + "domDM", +}; + +#define XEN_SID_SZ (sizeof(xen_sid_to_str)/sizeof(xen_sid_to_str[0])) + +static const uint32_t avtab_flavors[] = { + AVTAB_ALLOWED, + AVTAB_AUDITALLOW, + AVTAB_AUDITDENY, + AVTAB_XPERMS_ALLOWED, + AVTAB_XPERMS_AUDITALLOW, + AVTAB_XPERMS_DONTAUDIT, + AVTAB_TRANSITION, + AVTAB_MEMBER, + AVTAB_CHANGE, +}; + +#define AVTAB_FLAVORS_SZ (sizeof(avtab_flavors)/sizeof(avtab_flavors[0])) + +struct strs { + char **list; + unsigned num; + size_t size; +}; + +__attribute__ ((format(printf, 1, 2))) +void sepol_log_err(const char *fmt, ...); +void sepol_indent(FILE *out, int indent); +__attribute__ ((format(printf, 2, 3))) +void sepol_printf(FILE *out, const char *fmt, ...); + +__attribute__ ((format(printf, 1, 3))) +char *create_str(const char *fmt, int num, ...); + +int strs_init(struct strs **strs, size_t size); +void strs_destroy(struct strs **strs); +void strs_free_all(struct strs *strs); +int strs_add(struct strs *strs, char *s); +__attribute__ ((format(printf, 2, 4))) +int strs_create_and_add(struct strs *strs, const char *fmt, int num, ...); +char *strs_remove_last(struct strs *strs); +int strs_add_at_index(struct strs *strs, char *s, size_t index); +char *strs_read_at_index(struct strs *strs, size_t index); +void strs_sort(struct strs *strs); +unsigned strs_num_items(const struct strs *strs); +size_t strs_len_items(const struct strs *strs); +char *strs_to_str(const struct strs *strs); +void strs_write_each(const struct strs *strs, FILE *out); +void strs_write_each_indented(const struct strs *strs, FILE *out, int indent); +int hashtab_ordered_to_strs(char *key, void *data, void *args); +int ebitmap_to_strs(const struct ebitmap *map, struct strs *strs, char **val_to_name); +char *ebitmap_to_str(const struct ebitmap *map, char **val_to_name, int sort); + +int strs_stack_init(struct strs **stack); +void strs_stack_destroy(struct strs **stack); +int strs_stack_push(struct strs *stack, char *s); +char *strs_stack_pop(struct strs *stack); +int strs_stack_empty(const struct strs *stack); + +int sort_ocontexts(struct policydb *pdb); diff --git a/kernel/libsepol/src/kernel_to_conf.c b/kernel/libsepol/src/kernel_to_conf.c new file mode 100644 index 00000000..580eeafe --- /dev/null +++ b/kernel/libsepol/src/kernel_to_conf.c @@ -0,0 +1,3338 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kernel_to_common.h" + + +static char *cond_expr_to_str(struct policydb *pdb, struct cond_expr *expr) +{ + struct cond_expr *curr; + struct strs *stack; + char *new_val; + char *str = NULL; + int rc; + + rc = strs_stack_init(&stack); + if (rc != 0) { + goto exit; + } + + for (curr = expr; curr != NULL; curr = curr->next) { + if (curr->expr_type == COND_BOOL) { + char *val1 = pdb->p_bool_val_to_name[curr->bool - 1]; + new_val = create_str("%s", 1, val1); + } else { + const char *op; + uint32_t num_params; + char *val1 = NULL; + char *val2 = NULL; + + switch(curr->expr_type) { + case COND_NOT: op = "!"; num_params = 1; break; + case COND_OR: op = "||"; num_params = 2; break; + case COND_AND: op = "&&"; num_params = 2; break; + case COND_XOR: op = "^"; num_params = 2; break; + case COND_EQ: op = "=="; num_params = 2; break; + case COND_NEQ: op = "!="; num_params = 2; break; + default: + sepol_log_err("Unknown conditional operator: %i", curr->expr_type); + goto exit; + } + + if (num_params == 2) { + val2 = strs_stack_pop(stack); + if (!val2) { + sepol_log_err("Invalid conditional expression"); + goto exit; + } + } + val1 = strs_stack_pop(stack); + if (!val1) { + sepol_log_err("Invalid conditional expression"); + free(val2); + goto exit; + } + if (num_params == 2) { + new_val = create_str("(%s %s %s)", 3, val1, op, val2); + free(val2); + } else { + new_val = create_str("%s %s", 2, op, val1); + } + free(val1); + } + if (!new_val) { + sepol_log_err("Invalid conditional expression"); + goto exit; + } + rc = strs_stack_push(stack, new_val); + if (rc != 0) { + sepol_log_err("Out of memory"); + goto exit; + } + } + + new_val = strs_stack_pop(stack); + if (!new_val || !strs_stack_empty(stack)) { + sepol_log_err("Invalid conditional expression"); + goto exit; + } + + str = new_val; + + strs_stack_destroy(&stack); + return str; + +exit: + if (stack) { + while ((new_val = strs_stack_pop(stack)) != NULL) { + free(new_val); + } + strs_stack_destroy(&stack); + } + + return NULL; +} + +static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr *expr, int *use_mls) +{ + struct constraint_expr *curr; + struct strs *stack = NULL; + char *new_val = NULL; + const char *op; + char *str = NULL; + int rc; + + *use_mls = 0; + + rc = strs_stack_init(&stack); + if (rc != 0) { + goto exit; + } + + for (curr = expr; curr; curr = curr->next) { + if (curr->expr_type == CEXPR_ATTR || curr->expr_type == CEXPR_NAMES) { + const char *attr1 = NULL; + const char *attr2 = NULL; + + switch (curr->op) { + case CEXPR_EQ: op = "=="; break; + case CEXPR_NEQ: op = "!="; break; + case CEXPR_DOM: op = "dom"; break; + case CEXPR_DOMBY: op = "domby"; break; + case CEXPR_INCOMP: op = "incomp"; break; + default: + sepol_log_err("Unknown constraint operator: %i", curr->op); + goto exit; + } + + switch (curr->attr) { + case CEXPR_USER: attr1 ="u1"; attr2 ="u2"; break; + case CEXPR_USER | CEXPR_TARGET: attr1 ="u2"; attr2 =""; break; + case CEXPR_USER | CEXPR_XTARGET: attr1 ="u3"; attr2 =""; break; + case CEXPR_ROLE: attr1 ="r1"; attr2 ="r2"; break; + case CEXPR_ROLE | CEXPR_TARGET: attr1 ="r2"; attr2 =""; break; + case CEXPR_ROLE | CEXPR_XTARGET: attr1 ="r3"; attr2 =""; break; + case CEXPR_TYPE: attr1 ="t1"; attr2 ="t2"; break; + case CEXPR_TYPE | CEXPR_TARGET: attr1 ="t2"; attr2 =""; break; + case CEXPR_TYPE | CEXPR_XTARGET: attr1 ="t3"; attr2 =""; break; + case CEXPR_L1L2: attr1 ="l1"; attr2 ="l2"; break; + case CEXPR_L1H2: attr1 ="l1"; attr2 ="h2"; break; + case CEXPR_H1L2: attr1 ="h1"; attr2 ="l2"; break; + case CEXPR_H1H2: attr1 ="h1"; attr2 ="h2"; break; + case CEXPR_L1H1: attr1 ="l1"; attr2 ="h1"; break; + case CEXPR_L2H2: attr1 ="l2"; attr2 ="h2"; break; + default: + sepol_log_err("Unknown constraint attribute: %i", curr->attr); + goto exit; + } + + if (curr->attr >= CEXPR_XTARGET) { + *use_mls = 1; + } + + if (curr->expr_type == CEXPR_ATTR) { + new_val = create_str("%s %s %s", 3, attr1, op, attr2); + } else { + char *names = NULL; + if (curr->attr & CEXPR_TYPE) { + struct type_set *ts = curr->type_names; + names = ebitmap_to_str(&ts->types, pdb->p_type_val_to_name, 1); + } else if (curr->attr & CEXPR_USER) { + names = ebitmap_to_str(&curr->names, pdb->p_user_val_to_name, 1); + } else if (curr->attr & CEXPR_ROLE) { + names = ebitmap_to_str(&curr->names, pdb->p_role_val_to_name, 1); + } + if (!names) { + names = strdup("NO_IDENTIFIER"); + if (!names) { + sepol_log_err("Out of memory"); + goto exit; + } + } + if (strchr(names, ' ')) { + new_val = create_str("%s %s { %s }", 3, attr1, op, names); + } else { + new_val = create_str("%s %s %s", 3, attr1, op, names); + } + free(names); + } + } else { + uint32_t num_params; + char *val1 = NULL; + char *val2 = NULL; + + switch (curr->expr_type) { + case CEXPR_NOT: op = "not"; num_params = 1; break; + case CEXPR_AND: op = "and"; num_params = 2; break; + case CEXPR_OR: op = "or"; num_params = 2; break; + default: + sepol_log_err("Unknown constraint expression type: %i", curr->expr_type); + goto exit; + } + + if (num_params == 2) { + val2 = strs_stack_pop(stack); + if (!val2) { + sepol_log_err("Invalid constraint expression"); + goto exit; + } + } + val1 = strs_stack_pop(stack); + if (!val1) { + sepol_log_err("Invalid constraint expression"); + goto exit; + } + + if (num_params == 2) { + new_val = create_str("(%s %s %s)", 3, val1, op, val2); + free(val2); + } else { + new_val = create_str("%s (%s)", 2, op, val1); + } + free(val1); + } + if (!new_val) { + goto exit; + } + rc = strs_stack_push(stack, new_val); + if (rc != 0) { + sepol_log_err("Out of memory"); + goto exit; + } + } + + new_val = strs_stack_pop(stack); + if (!new_val || !strs_stack_empty(stack)) { + sepol_log_err("Invalid constraint expression"); + goto exit; + } + + str = new_val; + + strs_stack_destroy(&stack); + + return str; + +exit: + if (stack) { + while ((new_val = strs_stack_pop(stack)) != NULL) { + free(new_val); + } + strs_stack_destroy(&stack); + } + + return NULL; +} + +static int class_constraint_rules_to_strs(struct policydb *pdb, char *classkey, + class_datum_t *class, + struct constraint_node *constraint_rules, + struct strs *mls_list, + struct strs *non_mls_list) +{ + struct constraint_node *curr; + struct strs *strs; + const char *flavor, *perm_prefix, *perm_suffix; + char *perms, *expr; + int is_mls; + int rc = 0; + + for (curr = constraint_rules; curr != NULL; curr = curr->next) { + if (curr->permissions == 0) { + continue; + } + expr = constraint_expr_to_str(pdb, curr->expr, &is_mls); + if (!expr) { + rc = -1; + goto exit; + } + + perms = sepol_av_to_string(pdb, class->s.value, curr->permissions); + if (strchr(perms, ' ')) { + perm_prefix = "{ "; + perm_suffix = " }"; + } else { + perm_prefix = ""; + perm_suffix = ""; + } + if (is_mls) { + flavor = "mlsconstrain"; + strs = mls_list; + } else { + flavor = "constrain"; + strs = non_mls_list; + } + + rc = strs_create_and_add(strs, "%s %s %s%s%s %s;", 6, + flavor, classkey, + perm_prefix, perms+1, perm_suffix, + expr); + free(expr); + if (rc != 0) { + goto exit; + } + } + + return 0; +exit: + sepol_log_err("Error gathering constraint rules\n"); + return rc; +} + +static int class_validatetrans_rules_to_strs(struct policydb *pdb, char *classkey, + struct constraint_node *validatetrans_rules, + struct strs *mls_list, + struct strs *non_mls_list) +{ + struct constraint_node *curr; + struct strs *strs; + const char *flavor; + char *expr; + int is_mls; + int rc = 0; + + for (curr = validatetrans_rules; curr != NULL; curr = curr->next) { + expr = constraint_expr_to_str(pdb, curr->expr, &is_mls); + if (!expr) { + rc = -1; + goto exit; + } + + if (is_mls) { + flavor = "mlsvalidatetrans"; + strs = mls_list; + } else { + flavor = "validatetrans"; + strs = non_mls_list; + } + + rc = strs_create_and_add(strs, "%s %s %s;", 3, flavor, classkey, expr); + free(expr); + if (rc != 0) { + goto exit; + } + } + +exit: + return rc; +} + +static int constraint_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, struct strs *non_mls_strs) +{ + class_datum_t *class; + char *name; + unsigned i; + int rc = 0; + + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (class && class->constraints) { + name = pdb->p_class_val_to_name[i]; + rc = class_constraint_rules_to_strs(pdb, name, class, class->constraints, mls_strs, non_mls_strs); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(mls_strs); + strs_sort(non_mls_strs); + +exit: + return rc; +} + +static int validatetrans_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, struct strs *non_mls_strs) +{ + class_datum_t *class; + char *name; + unsigned i; + int rc = 0; + + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (class && class->validatetrans) { + name = pdb->p_class_val_to_name[i]; + rc = class_validatetrans_rules_to_strs(pdb, name, class->validatetrans, mls_strs, non_mls_strs); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(mls_strs); + strs_sort(non_mls_strs); + +exit: + return rc; +} + +static int write_handle_unknown_to_conf(FILE *out, struct policydb *pdb) +{ + const char *action; + + switch (pdb->handle_unknown) { + case SEPOL_DENY_UNKNOWN: + action = "deny"; + break; + case SEPOL_REJECT_UNKNOWN: + action = "reject"; + break; + case SEPOL_ALLOW_UNKNOWN: + action = "allow"; + break; + default: + sepol_log_err("Unknown value for handle-unknown: %i", pdb->handle_unknown); + return -1; + } + + sepol_printf(out, "# handle_unknown %s\n", action); + + return 0; +} + +static int write_class_decl_rules_to_conf(FILE *out, struct policydb *pdb) +{ + char *name; + unsigned i; + + for (i=0; i < pdb->p_classes.nprim; i++) { + name = pdb->p_class_val_to_name[i]; + sepol_printf(out, "class %s\n", name); + } + + return 0; +} + +static int write_sids_to_conf(FILE *out, const char *const *sid_to_str, + unsigned num_sids, struct ocontext *isids) +{ + struct ocontext *isid; + struct strs *strs; + char *sid; + char unknown[18]; + unsigned i; + int rc; + + rc = strs_init(&strs, num_sids+1); + if (rc != 0) { + goto exit; + } + + for (isid = isids; isid != NULL; isid = isid->next) { + i = isid->sid[0]; + if (i < num_sids) { + sid = (char *)sid_to_str[i]; + } else { + snprintf(unknown, sizeof(unknown), "%s%u", "UNKNOWN", i); + sid = strdup(unknown); + if (!sid) { + rc = -1; + goto exit; + } + } + rc = strs_add_at_index(strs, sid, i); + if (rc != 0) { + goto exit; + } + } + + for (i=0; itarget_platform == SEPOL_TARGET_SELINUX) { + rc = write_sids_to_conf(out, selinux_sid_to_str, SELINUX_SID_SZ, + pdb->ocontexts[0]); + } else if (pdb->target_platform == SEPOL_TARGET_XEN) { + rc = write_sids_to_conf(out, xen_sid_to_str, XEN_SID_SZ, + pdb->ocontexts[0]); + } else { + sepol_log_err("Unknown target platform: %i", pdb->target_platform); + rc = -1; + } + + return rc; +} +static char *class_or_common_perms_to_str(symtab_t *permtab) +{ + struct strs *strs; + char *perms = NULL; + int rc = 0; + + rc = strs_init(&strs, permtab->nprim); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(permtab->table, hashtab_ordered_to_strs, strs); + if (rc != 0) { + goto exit; + } + + if (strs_num_items(strs) > 0) { + perms = strs_to_str(strs); + } + +exit: + strs_destroy(&strs); + + return perms; +} + +static int write_class_and_common_rules_to_conf(FILE *out, struct policydb *pdb) +{ + class_datum_t *class; + common_datum_t *common; + int *used; + char *name, *perms; + unsigned i; + int rc = 0; + + /* common */ + used = calloc(pdb->p_commons.nprim, sizeof(*used)); + if (!used) { + sepol_log_err("Out of memory"); + rc = -1; + goto exit; + } + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + name = class->comkey; + if (!name) continue; + common = hashtab_search(pdb->p_commons.table, name); + if (!common) { + rc = -1; + free(used); + goto exit; + } + /* Only write common rule once */ + if (!used[common->s.value-1]) { + perms = class_or_common_perms_to_str(&common->permissions); + if (!perms) { + rc = -1; + free(used); + goto exit; + } + sepol_printf(out, "common %s { %s }\n", name, perms); + free(perms); + used[common->s.value-1] = 1; + } + } + free(used); + + /* class */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + name = pdb->p_class_val_to_name[i]; + sepol_printf(out, "class %s", name); + if (class->comkey) { + sepol_printf(out, " inherits %s", class->comkey); + } + perms = class_or_common_perms_to_str(&class->permissions); + if (perms) { + sepol_printf(out, " { %s }", perms); + free(perms); + } + sepol_printf(out, "\n"); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing class rules to policy.conf\n"); + } + + return rc; +} + +static int write_default_user_to_conf(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_user) { + case DEFAULT_SOURCE: + dft = "source"; + break; + case DEFAULT_TARGET: + dft = "target"; + break; + default: + sepol_log_err("Unknown default role value: %i", class->default_user); + return -1; + } + sepol_printf(out, "default_user { %s } %s;\n", class_name, dft); + + return 0; +} + +static int write_default_role_to_conf(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_role) { + case DEFAULT_SOURCE: + dft = "source"; + break; + case DEFAULT_TARGET: + dft = "target"; + break; + default: + sepol_log_err("Unknown default role value: %i", class->default_role); + return -1; + } + sepol_printf(out, "default_role { %s } %s;\n", class_name, dft); + + return 0; +} + +static int write_default_type_to_conf(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_type) { + case DEFAULT_SOURCE: + dft = "source"; + break; + case DEFAULT_TARGET: + dft = "target"; + break; + default: + sepol_log_err("Unknown default type value: %i", class->default_type); + return -1; + } + sepol_printf(out, "default_type { %s } %s;\n", class_name, dft); + + return 0; +} + +static int write_default_range_to_conf(FILE *out, char *class_name, class_datum_t *class) +{ + const char *dft; + + switch (class->default_range) { + case DEFAULT_SOURCE_LOW: + dft = "source low"; + break; + case DEFAULT_SOURCE_HIGH: + dft = "source high"; + break; + case DEFAULT_SOURCE_LOW_HIGH: + dft = "source low-high"; + break; + case DEFAULT_TARGET_LOW: + dft = "target low"; + break; + case DEFAULT_TARGET_HIGH: + dft = "target high"; + break; + case DEFAULT_TARGET_LOW_HIGH: + dft = "target low-high"; + break; + case DEFAULT_GLBLUB: + dft = "glblub"; + break; + default: + sepol_log_err("Unknown default type value: %i", class->default_range); + return -1; + } + sepol_printf(out, "default_range { %s } %s;\n", class_name, dft); + + return 0; +} + +static int write_default_rules_to_conf(FILE *out, struct policydb *pdb) +{ + class_datum_t *class; + unsigned i; + int rc = 0; + + /* default_user */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_user != 0) { + rc = write_default_user_to_conf(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + + /* default_role */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_role != 0) { + rc = write_default_role_to_conf(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + + /* default_type */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_type != 0) { + rc = write_default_type_to_conf(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + + if (!pdb->mls) { + return 0; + } + + /* default_range */ + for (i=0; i < pdb->p_classes.nprim; i++) { + class = pdb->class_val_to_struct[i]; + if (!class) continue; + if (class->default_range != 0) { + rc = write_default_range_to_conf(out, pdb->p_class_val_to_name[i], class); + if (rc != 0) { + goto exit; + } + } + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing default rules to policy.conf\n"); + } + + return rc; +} + +static int map_sensitivity_aliases_to_strs(char *key, void *data, void *args) +{ + level_datum_t *sens = data; + struct strs *strs = args; + int rc = 0; + + if (sens->isalias) { + rc = strs_add(strs, key); + } + + return rc; +} + +static int write_sensitivity_rules_to_conf(FILE *out, struct policydb *pdb) +{ + level_datum_t *level; + struct strs *strs; + char **sens_alias_map = NULL; + char *name, *prev, *alias; + unsigned i, j, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_levels.nprim); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_levels.table, map_sensitivity_aliases_to_strs, strs); + if (rc != 0) { + goto exit; + } + + num = strs_num_items(strs); + + if (num > 0) { + sens_alias_map = calloc(sizeof(*sens_alias_map), pdb->p_levels.nprim); + if (!sens_alias_map) { + rc = -1; + goto exit; + } + + /* map aliases to sensitivities */ + for (i=0; i < num; i++) { + name = strs_read_at_index(strs, i); + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + j = level->level->sens - 1; + if (!sens_alias_map[j]) { + sens_alias_map[j] = strdup(name); + if (!sens_alias_map[j]) { + rc = -1; + goto exit; + } + } else { + alias = sens_alias_map[j]; + sens_alias_map[j] = create_str("%s %s", 2, alias, name); + free(alias); + if (!sens_alias_map[j]) { + rc = -1; + goto exit; + } + } + } + } + + /* sensitivities */ + for (i=0; i < pdb->p_levels.nprim; i++) { + name = pdb->p_sens_val_to_name[i]; + if (!name) continue; + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + if (level->isalias) continue; + + if (sens_alias_map && sens_alias_map[i]) { + alias = sens_alias_map[i]; + if (strchr(alias, ' ')) { + sepol_printf(out, "sensitivity %s alias { %s };\n", name, alias); + } else { + sepol_printf(out, "sensitivity %s alias %s;\n", name, alias); + } + } else { + sepol_printf(out, "sensitivity %s;\n", name); + } + } + + /* dominance */ + sepol_printf(out, "dominance { "); + prev = NULL; + for (i=0; i < pdb->p_levels.nprim; i++) { + name = pdb->p_sens_val_to_name[i]; + if (!name) continue; + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + if (level->isalias) continue; + + if (prev) { + sepol_printf(out, "%s ", prev); + } + prev = name; + } + if (prev) { + sepol_printf(out, "%s", prev); + } + sepol_printf(out, " }\n"); + +exit: + if (sens_alias_map) { + for (i=0; i < pdb->p_levels.nprim; i++) { + free(sens_alias_map[i]); + } + free(sens_alias_map); + } + + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing sensitivity rules to CIL\n"); + } + + return rc; +} + +static int map_category_aliases_to_strs(char *key, void *data, void *args) +{ + cat_datum_t *cat = data; + struct strs *strs = args; + int rc = 0; + + if (cat->isalias) { + rc = strs_add(strs, key); + } + + return rc; +} + +static int write_category_rules_to_conf(FILE *out, struct policydb *pdb) +{ + cat_datum_t *cat; + struct strs *strs; + char **cat_alias_map = NULL; + char *name, *alias; + unsigned i, j, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_cats.nprim); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_cats.table, map_category_aliases_to_strs, strs); + if (rc != 0) { + goto exit; + } + + num = strs_num_items(strs); + + if (num > 0) { + cat_alias_map = calloc(sizeof(*cat_alias_map), pdb->p_cats.nprim); + if (!cat_alias_map) { + rc = -1; + goto exit; + } + + /* map aliases to categories */ + for (i=0; i < num; i++) { + name = strs_read_at_index(strs, i); + cat = hashtab_search(pdb->p_cats.table, name); + if (!cat) { + rc = -1; + goto exit; + } + j = cat->s.value - 1; + if (!cat_alias_map[j]) { + cat_alias_map[j] = strdup(name); + if (!cat_alias_map[j]) { + rc = -1; + goto exit; + } + } else { + alias = cat_alias_map[j]; + cat_alias_map[j] = create_str("%s %s", 2, alias, name); + free(alias); + if (!cat_alias_map[j]) { + rc = -1; + goto exit; + } + } + } + } + + /* categories */ + for (i=0; i < pdb->p_cats.nprim; i++) { + name = pdb->p_cat_val_to_name[i]; + if (!name) continue; + cat = hashtab_search(pdb->p_cats.table, name); + if (!cat) { + rc = -1; + goto exit; + } + if (cat->isalias) continue; + + if (cat_alias_map && cat_alias_map[i]) { + alias = cat_alias_map[i]; + if (strchr(alias, ' ')) { + sepol_printf(out, "category %s alias { %s };\n", name, alias); + } else { + sepol_printf(out, "category %s alias %s;\n", name, alias); + } + } else { + sepol_printf(out, "category %s;\n", name); + } + } + +exit: + if (cat_alias_map) { + for (i=0; i < pdb->p_cats.nprim; i++) { + free(cat_alias_map[i]); + } + free(cat_alias_map); + } + + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing category rules to policy.conf\n"); + } + + return rc; +} + +static size_t cats_ebitmap_len(struct ebitmap *cats, char **val_to_name) +{ + struct ebitmap_node *node; + uint32_t i, start, range; + size_t len = 0; + + range = 0; + ebitmap_for_each_positive_bit(cats, node, i) { + if (range == 0) + start = i; + + range++; + + if (ksu_ebitmap_get_bit(cats, i+1)) + continue; + + len += strlen(val_to_name[start]) + 1; + if (range > 1) { + len += strlen(val_to_name[i]) + 1; + } + + range = 0; + } + + return len; +} + +static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name) +{ + struct ebitmap_node *node; + uint32_t i, start, range, first; + char *catsbuf = NULL, *p; + char sep; + int len, remaining; + + remaining = (int)cats_ebitmap_len(cats, val_to_name); + if (remaining == 0) { + goto exit; + } + catsbuf = malloc(remaining); + if (!catsbuf) { + goto exit; + } + + p = catsbuf; + + first = 1; + range = 0; + ebitmap_for_each_positive_bit(cats, node, i) { + if (range == 0) + start = i; + + range++; + + if (ksu_ebitmap_get_bit(cats, i+1)) + continue; + + if (range > 1) { + sep = (range == 2) ? ',' : '.'; + len = snprintf(p, remaining, "%s%s%c%s", + first ? "" : ",", + val_to_name[start], sep, val_to_name[i]); + } else { + len = snprintf(p, remaining, "%s%s", first ? "" : ",", + val_to_name[start]); + + } + if (len < 0 || len >= remaining) { + goto exit; + } + p += len; + remaining -= len; + first = 0; + range = 0; + } + + *p = '\0'; + + return catsbuf; + +exit: + free(catsbuf); + return NULL; +} + +static int write_level_rules_to_conf(FILE *out, struct policydb *pdb) +{ + level_datum_t *level; + char *name, *cats; + unsigned i; + int rc = 0; + + for (i=0; i < pdb->p_levels.nprim; i++) { + name = pdb->p_sens_val_to_name[i]; + if (!name) continue; + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + if (level->isalias) continue; + + if (!ebitmap_is_empty(&level->level->cat)) { + cats = cats_ebitmap_to_str(&level->level->cat, pdb->p_cat_val_to_name); + sepol_printf(out, "level %s:%s;\n", name, cats); + free(cats); + } else { + sepol_printf(out, "level %s;\n", name); + } + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing level rules to policy.conf\n"); + } + + return rc; +} + +static int write_mls_rules_to_conf(FILE *out, struct policydb *pdb) +{ + int rc = 0; + + if (!pdb->mls) { + return 0; + } + + rc = write_sensitivity_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_category_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_level_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing mls rules to policy.conf\n"); + } + + return rc; +} + +static int write_polcap_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct strs *strs; + struct ebitmap_node *node; + const char *name; + uint32_t i; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + ebitmap_for_each_positive_bit(&pdb->policycaps, node, i) { + name = sepol_polcap_getname(i); + if (name == NULL) { + sepol_log_err("Unknown policy capability id: %i", i); + rc = -1; + goto exit; + } + + rc = strs_create_and_add(strs, "policycap %s;", 1, name); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing polcap rules to policy.conf\n"); + } + + return rc; +} + +static int write_type_attributes_to_conf(FILE *out, struct policydb *pdb) +{ + type_datum_t *type; + char *name; + struct strs *strs; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type = pdb->type_val_to_struct[i]; + if (type && type->flavor == TYPE_ATTRIB) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i = 0; i < num; i++) { + name = strs_read_at_index(strs, i); + if (!name) { + rc = -1; + goto exit; + } + sepol_printf(out, "attribute %s;\n", name); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing typeattribute rules to policy.conf\n"); + } + + return rc; +} + +static int write_role_attributes_to_conf(FILE *out, struct policydb *pdb) +{ + role_datum_t *role; + char *name; + struct strs *strs; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_roles.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_roles.nprim; i++) { + role = pdb->role_val_to_struct[i]; + if (role && role->flavor == ROLE_ATTRIB) { + rc = strs_add(strs, pdb->p_role_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; istate ? "true" : "false"; + + return strs_create_and_add(strs, "bool %s %s;", 2, key, value); +} + +static int write_boolean_decl_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_bools.table, map_boolean_to_strs, strs); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing boolean declarations to policy.conf\n"); + } + + return rc; +} + +static int write_type_decl_rules_to_conf(FILE *out, struct policydb *pdb) +{ + type_datum_t *type; + struct strs *strs; + char *name; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type = pdb->type_val_to_struct[i]; + if (type && type->flavor == TYPE_TYPE && type->primary) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; iprimary == 0 && datum->flavor == TYPE_TYPE) + (*count)++; + + return SEPOL_OK; +} + +static int map_type_aliases_to_strs(char *key, void *data, void *args) +{ + type_datum_t *datum = data; + struct strs *strs = args; + int rc = 0; + + if (datum->primary == 0 && datum->flavor == TYPE_TYPE) + rc = strs_add(strs, key); + + return rc; +} + +static int write_type_alias_rules_to_conf(FILE *out, struct policydb *pdb) +{ + type_datum_t *alias; + struct strs *strs; + char *name; + char *type; + unsigned i, num = 0; + int rc = 0; + + rc = ksu_hashtab_map(pdb->p_types.table, map_count_type_aliases, &num); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&strs, num); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(pdb->p_types.table, map_type_aliases_to_strs, strs); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + + for (i=0; ip_types.table, name); + if (!alias) { + rc = -1; + goto exit; + } + type = pdb->p_type_val_to_name[alias->s.value - 1]; + sepol_printf(out, "typealias %s alias %s;\n", type, name); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing type alias rules to policy.conf\n"); + } + + return rc; +} + +static int write_type_bounds_rules_to_conf(FILE *out, struct policydb *pdb) +{ + type_datum_t *type; + struct strs *strs; + char *parent; + char *child; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type = pdb->type_val_to_struct[i]; + if (type && type->flavor == TYPE_TYPE) { + if (type->bounds > 0) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; ip_types.table, child); + if (!type) { + rc = -1; + goto exit; + } + parent = pdb->p_type_val_to_name[type->bounds - 1]; + sepol_printf(out, "typebounds %s %s;\n", parent, child); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing type bounds rules to policy.conf\n"); + } + + return rc; +} + +static char *attr_strs_to_str(struct strs *strs) +{ + char *str = NULL; + size_t len = 0; + char *p; + unsigned i; + int rc; + + if (strs->num == 0) { + goto exit; + } + + /* 2*strs->num - 1 because ", " follows all but last attr (followed by '\0') */ + len = strs_len_items(strs) + 2*strs->num - 1; + str = malloc(len); + if (!str) { + sepol_log_err("Out of memory"); + goto exit; + } + + p = str; + for (i=0; inum; i++) { + if (!strs->list[i]) continue; + len = strlen(strs->list[i]); + rc = snprintf(p, len+1, "%s", strs->list[i]); + if (rc < 0 || rc > (int)len) { + free(str); + str = NULL; + goto exit; + } + p += len; + if (i < strs->num - 1) { + *p++ = ','; + *p++ = ' '; + } + } + + *p = '\0'; + +exit: + return str; +} + +static char *attrmap_to_str(struct ebitmap *map, char **val_to_name) +{ + struct strs *strs; + char *str = NULL; + int rc; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + rc = ebitmap_to_strs(map, strs, val_to_name); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + + str = attr_strs_to_str(strs); + +exit: + strs_destroy(&strs); + + return str; +} + +static int write_type_attribute_sets_to_conf(FILE *out, struct policydb *pdb) +{ + type_datum_t *type; + struct strs *strs; + ebitmap_t attrmap; + char *name, *attrs; + unsigned i; + int rc; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_types.nprim; i++) { + type = pdb->type_val_to_struct[i]; + if (!type || type->flavor != TYPE_TYPE || !type->primary) continue; + if (ebitmap_cardinality(&pdb->type_attr_map[i]) == 1) continue; + + rc = ksu_ebitmap_cpy(&attrmap, &pdb->type_attr_map[i]); + if (rc != 0) { + goto exit; + } + rc = ksu_ebitmap_set_bit(&attrmap, i, 0); + if (rc != 0) { + ksu_ebitmap_destroy(&attrmap); + goto exit; + } + name = pdb->p_type_val_to_name[i]; + attrs = attrmap_to_str(&attrmap, pdb->p_type_val_to_name); + ksu_ebitmap_destroy(&attrmap); + if (!attrs) { + rc = -1; + goto exit; + } + + rc = strs_create_and_add(strs, "typeattribute %s %s;", + 2, name, attrs); + free(attrs); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing typeattributeset rules to policy.conf\n"); + } + + return rc; +} + +static int write_type_permissive_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct strs *strs; + char *name; + struct ebitmap_node *node; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_types.nprim); + if (rc != 0) { + goto exit; + } + + ebitmap_for_each_positive_bit(&pdb->permissive_map, node, i) { + rc = strs_add(strs, pdb->p_type_val_to_name[i-1]); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + for (i=0; idata; + type_datum_t *type; + const char *flavor, *src, *tgt, *class, *perms, *new; + char *rule = NULL; + + switch (0xFFF & key->specified) { + case AVTAB_ALLOWED: + flavor = "allow"; + break; + case AVTAB_AUDITALLOW: + flavor = "auditallow"; + break; + case AVTAB_AUDITDENY: + flavor = "dontaudit"; + data = ~data; + break; + case AVTAB_XPERMS_ALLOWED: + flavor = "allowxperm"; + break; + case AVTAB_XPERMS_AUDITALLOW: + flavor = "auditallowxperm"; + break; + case AVTAB_XPERMS_DONTAUDIT: + flavor = "dontauditxperm"; + break; + case AVTAB_TRANSITION: + flavor = "type_transition"; + break; + case AVTAB_MEMBER: + flavor = "type_member"; + break; + case AVTAB_CHANGE: + flavor = "type_change"; + break; + default: + sepol_log_err("Unknown avtab type: %i", key->specified); + goto exit; + } + + src = pdb->p_type_val_to_name[key->source_type - 1]; + tgt = pdb->p_type_val_to_name[key->target_type - 1]; + if (key->source_type == key->target_type && !(key->specified & AVTAB_TYPE)) { + type = pdb->type_val_to_struct[key->source_type - 1]; + if (type->flavor != TYPE_ATTRIB) { + tgt = "self"; + } + } + class = pdb->p_class_val_to_name[key->target_class - 1]; + + if (key->specified & AVTAB_AV) { + perms = sepol_av_to_string(pdb, key->target_class, data); + if (perms == NULL) { + sepol_log_err("Failed to generate permission string"); + goto exit; + } + rule = create_str("%s %s %s:%s { %s };", 5, + flavor, src, tgt, class, perms+1); + } else if (key->specified & AVTAB_XPERMS) { + perms = sepol_extended_perms_to_string(datum->xperms); + if (perms == NULL) { + sepol_log_err("Failed to generate extended permission string"); + goto exit; + } + + rule = create_str("%s %s %s:%s %s;", 5, flavor, src, tgt, class, perms); + } else { + new = pdb->p_type_val_to_name[data - 1]; + + rule = create_str("%s %s %s:%s %s;", 5, flavor, src, tgt, class, new); + } + + if (!rule) { + goto exit; + } + + return rule; + +exit: + return NULL; +} + +struct map_avtab_args { + struct policydb *pdb; + uint32_t flavor; + struct strs *strs; +}; + +static int map_avtab_write_helper(avtab_key_t *key, avtab_datum_t *datum, void *args) +{ + struct map_avtab_args *map_args = args; + uint32_t flavor = map_args->flavor; + struct policydb *pdb = map_args->pdb; + struct strs *strs = map_args->strs; + char *rule; + int rc = 0; + + if (key->specified & flavor) { + rule = avtab_node_to_str(pdb, key, datum); + if (!rule) { + rc = -1; + goto exit; + } + rc = strs_add(strs, rule); + if (rc != 0) { + free(rule); + goto exit; + } + } + +exit: + return rc; +} + +static int write_avtab_flavor_to_conf(FILE *out, struct policydb *pdb, uint32_t flavor, int indent) +{ + struct map_avtab_args args; + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 1000); + if (rc != 0) { + goto exit; + } + + args.pdb = pdb; + args.flavor = flavor; + args.strs = strs; + + rc = avtab_map(&pdb->te_avtab, map_avtab_write_helper, &args); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each_indented(strs, out, indent); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + return rc; +} + +static int write_avtab_to_conf(FILE *out, struct policydb *pdb, int indent) +{ + unsigned i; + int rc = 0; + + for (i = 0; i < AVTAB_FLAVORS_SZ; i++) { + rc = write_avtab_flavor_to_conf(out, pdb, avtab_flavors[i], indent); + if (rc != 0) { + goto exit; + } + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing avtab rules to policy.conf\n"); + } + + return rc; +} + +struct map_filename_trans_args { + struct policydb *pdb; + struct strs *strs; +}; + +static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg) +{ + filename_trans_key_t *ft = (filename_trans_key_t *)key; + filename_trans_datum_t *datum = data; + struct map_filename_trans_args *map_args = arg; + struct policydb *pdb = map_args->pdb; + struct strs *strs = map_args->strs; + char *src, *tgt, *class, *filename, *new; + struct ebitmap_node *node; + uint32_t bit; + int rc; + + tgt = pdb->p_type_val_to_name[ft->ttype - 1]; + class = pdb->p_class_val_to_name[ft->tclass - 1]; + filename = ft->name; + do { + new = pdb->p_type_val_to_name[datum->otype - 1]; + + ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { + src = pdb->p_type_val_to_name[bit]; + rc = strs_create_and_add(strs, + "type_transition %s %s:%s %s \"%s\";", + 5, src, tgt, class, new, filename); + if (rc) + return rc; + } + + datum = datum->next; + } while (datum); + + return 0; +} + +static int write_filename_trans_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct map_filename_trans_args args; + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 100); + if (rc != 0) { + goto exit; + } + + args.pdb = pdb; + args.strs = strs; + + rc = ksu_hashtab_map(pdb->filename_trans, map_filename_trans_to_str, &args); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing filename typetransition rules to policy.conf\n"); + } + + return rc; +} + +static char *level_to_str(struct policydb *pdb, struct mls_level *level) +{ + ebitmap_t *cats = &level->cat; + char *level_str = NULL; + char *sens_str = pdb->p_sens_val_to_name[level->sens - 1]; + char *cats_str; + + if (!ebitmap_is_empty(cats)) { + cats_str = cats_ebitmap_to_str(cats, pdb->p_cat_val_to_name); + level_str = create_str("%s:%s", 2, sens_str, cats_str); + free(cats_str); + } else { + level_str = create_str("%s", 1, sens_str); + } + + return level_str; +} + +static char *range_to_str(struct policydb *pdb, mls_range_t *range) +{ + char *low = NULL; + char *high = NULL; + char *range_str = NULL; + + low = level_to_str(pdb, &range->level[0]); + if (!low) { + goto exit; + } + + high = level_to_str(pdb, &range->level[1]); + if (!high) { + goto exit; + } + + range_str = create_str("%s - %s", 2, low, high); + +exit: + free(low); + free(high); + + return range_str; +} + +struct map_range_trans_args { + struct policydb *pdb; + struct strs *strs; +}; + +static int map_range_trans_to_str(hashtab_key_t key, void *data, void *arg) +{ + range_trans_t *rt = (range_trans_t *)key; + mls_range_t *mls_range = data; + struct map_range_trans_args *map_args = arg; + struct policydb *pdb = map_args->pdb; + struct strs *strs = map_args->strs; + char *src, *tgt, *class, *range; + int rc; + + src = pdb->p_type_val_to_name[rt->source_type - 1]; + tgt = pdb->p_type_val_to_name[rt->target_type - 1]; + class = pdb->p_class_val_to_name[rt->target_class - 1]; + range = range_to_str(pdb, mls_range); + if (!range) { + rc = -1; + goto exit; + } + + rc = strs_create_and_add(strs, "range_transition %s %s:%s %s;", 4, + src, tgt, class, range); + free(range); + if (rc != 0) { + goto exit; + } + +exit: + return rc; +} + +static int write_range_trans_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct map_range_trans_args args; + struct strs *strs; + int rc = 0; + + rc = strs_init(&strs, 100); + if (rc != 0) { + goto exit; + } + + args.pdb = pdb; + args.strs = strs; + + rc = ksu_hashtab_map(pdb->range_tr, map_range_trans_to_str, &args); + if (rc != 0) { + goto exit; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing range transition rules to policy.conf\n"); + } + + return rc; +} + +static int write_cond_av_list_to_conf(FILE *out, struct policydb *pdb, cond_av_list_t *cond_list, int indent) +{ + cond_av_list_t *cond_av; + avtab_ptr_t node; + uint32_t flavor; + avtab_key_t *key; + avtab_datum_t *datum; + struct strs *strs; + char *rule; + unsigned i; + int rc; + + for (i = 0; i < AVTAB_FLAVORS_SZ; i++) { + flavor = avtab_flavors[i]; + rc = strs_init(&strs, 64); + if (rc != 0) { + goto exit; + } + + for (cond_av = cond_list; cond_av != NULL; cond_av = cond_av->next) { + node = cond_av->node; + key = &node->key; + datum = &node->datum; + if (key->specified & flavor) { + rule = avtab_node_to_str(pdb, key, datum); + if (!rule) { + rc = -1; + goto exit; + } + rc = strs_add(strs, rule); + if (rc != 0) { + free(rule); + goto exit; + } + } + } + + strs_sort(strs); + strs_write_each_indented(strs, out, indent); + strs_free_all(strs); + strs_destroy(&strs); + } + + return 0; + +exit: + strs_free_all(strs); + strs_destroy(&strs); + return rc; +} + +struct cond_data { + char *expr; + struct cond_node *cond; +}; + +static int cond_node_cmp(const void *a, const void *b) +{ + const struct cond_data *aa = a; + const struct cond_data *bb = b; + return strcmp(aa->expr, bb->expr); +} + +static int write_cond_nodes_to_conf(FILE *out, struct policydb *pdb) +{ + struct cond_data *cond_data; + char *expr; + struct cond_node *cond; + unsigned i, num; + int rc = 0; + + num = 0; + for (cond = pdb->cond_list; cond != NULL; cond = cond->next) { + num++; + } + + if (num == 0) { + return 0; + } + + cond_data = calloc(sizeof(struct cond_data), num); + if (!cond_data) { + rc = -1; + goto exit; + } + + i = 0; + for (cond = pdb->cond_list; cond != NULL; cond = cond->next) { + cond_data[i].cond = cond; + expr = cond_expr_to_str(pdb, cond->expr); + if (!expr) { + num = i; + goto exit; + } + cond_data[i].expr = expr; + i++; + } + + qsort(cond_data, num, sizeof(*cond_data), cond_node_cmp); + + for (i=0; itrue_list != NULL) { + rc = write_cond_av_list_to_conf(out, pdb, cond->true_list, 1); + if (rc != 0) { + goto exit; + } + } + + if (cond->false_list != NULL) { + sepol_printf(out, "} else {\n"); + rc = write_cond_av_list_to_conf(out, pdb, cond->false_list, 1); + if (rc != 0) { + goto exit; + } + } + sepol_printf(out, "}\n"); + } + +exit: + if (cond_data) { + for (i=0; ip_roles.nprim); + if (rc != 0) { + goto exit; + } + + /* Start at 1 to skip object_r */ + for (i=1; i < pdb->p_roles.nprim; i++) { + role = pdb->role_val_to_struct[i]; + if (role && role->flavor == ROLE_ROLE) { + rc = strs_add(strs, pdb->p_role_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + + for (i=0; ip_roles.table, name); + if (!role) { + rc = -1; + goto exit; + } + if (ebitmap_is_empty(&role->types.types)) continue; + types = ebitmap_to_str(&role->types.types, pdb->p_type_val_to_name, 1); + if (!types) { + rc = -1; + goto exit; + } + if (strlen(types) > 900) { + p1 = types; + while (p1) { + p2 = p1; + while (p2 - p1 < 600) { + p2 = strchr(p2, ' '); + if (!p2) + break; + p2++; + } + if (p2) { + *(p2-1) = '\0'; + } + sepol_printf(out, "role %s types { %s };\n", name, p1); + p1 = p2; + } + } else { + sepol_printf(out, "role %s types { %s };\n", name, types); + } + free(types); + } + +exit: + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing role declarations to policy.conf\n"); + } + + return rc; +} + +static int write_role_transition_rules_to_conf(FILE *out, struct policydb *pdb) +{ + role_trans_t *curr = pdb->role_tr; + struct strs *strs; + char *role, *type, *class, *new; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + while (curr) { + role = pdb->p_role_val_to_name[curr->role - 1]; + type = pdb->p_type_val_to_name[curr->type - 1]; + class = pdb->p_class_val_to_name[curr->tclass - 1]; + new = pdb->p_role_val_to_name[curr->new_role - 1]; + + rc = strs_create_and_add(strs, "role_transition %s %s:%s %s;", 4, + role, type, class, new); + if (rc != 0) { + goto exit; + } + + curr = curr->next; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing role transition rules to policy.conf\n"); + } + + return rc; +} + +static int write_role_allow_rules_to_conf(FILE *out, struct policydb *pdb) +{ + role_allow_t *curr = pdb->role_allow; + struct strs *strs; + char *role, *new; + int rc = 0; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + while (curr) { + role = pdb->p_role_val_to_name[curr->role - 1]; + new = pdb->p_role_val_to_name[curr->new_role - 1]; + + rc = strs_create_and_add(strs, "allow %s %s;", 2, role, new); + if (rc != 0) { + goto exit; + } + + curr = curr->next; + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing role allow rules to policy.conf\n"); + } + + return rc; +} + +static int write_user_decl_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct user_datum *user; + struct strs *strs; + char *name, *roles, *level, *range; + unsigned i, num; + int rc = 0; + + rc = strs_init(&strs, pdb->p_users.nprim); + if (rc != 0) { + goto exit; + } + + for (i=0; i < pdb->p_users.nprim; i++) { + if (!pdb->p_user_val_to_name[i]) continue; + rc = strs_add(strs, pdb->p_user_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } + + strs_sort(strs); + + num = strs_num_items(strs); + + for (i=0; ip_users.table, name); + if (!user) { + rc = -1; + goto exit; + } + sepol_printf(out, "user %s", name); + + if (!ebitmap_is_empty(&user->roles.roles)) { + roles = ebitmap_to_str(&user->roles.roles, + pdb->p_role_val_to_name, 1); + if (!roles) { + rc = -1; + goto exit; + } + if (strchr(roles, ' ')) { + sepol_printf(out, " roles { %s }", roles); + } else { + sepol_printf(out, " roles %s", roles); + } + free(roles); + } + + if (pdb->mls) { + level = level_to_str(pdb, &user->exp_dfltlevel); + if (!level) { + rc = -1; + goto exit; + } + sepol_printf(out, " level %s", level); + free(level); + + range = range_to_str(pdb, &user->exp_range); + if (!range) { + rc = -1; + goto exit; + } + sepol_printf(out, " range %s", range); + free(range); + } + sepol_printf(out, ";\n"); + } + +exit: + if (strs) + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing user declarations to policy.conf\n"); + } + + return rc; +} + +static char *context_to_str(struct policydb *pdb, struct context_struct *con) +{ + char *user, *role, *type, *range; + char *ctx = NULL; + + user = pdb->p_user_val_to_name[con->user - 1]; + role = pdb->p_role_val_to_name[con->role - 1]; + type = pdb->p_type_val_to_name[con->type - 1]; + + if (pdb->mls) { + range = range_to_str(pdb, &con->range); + ctx = create_str("%s:%s:%s:%s", 4, user, role, type, range); + free(range); + } else { + ctx = create_str("%s:%s:%s", 3, user, role, type); + } + + return ctx; +} + +static int write_sid_context_rules_to_conf(FILE *out, struct policydb *pdb, const char *const *sid_to_str, unsigned num_sids) +{ + struct ocontext *isid; + struct strs *strs; + char *sid; + char unknown[18]; + char *ctx, *rule; + unsigned i; + int rc; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + for (isid = pdb->ocontexts[0]; isid != NULL; isid = isid->next) { + i = isid->sid[0]; + if (i < num_sids) { + sid = (char *)sid_to_str[i]; + } else { + snprintf(unknown, sizeof(unknown), "%s%u", "UNKNOWN", i); + sid = unknown; + } + + ctx = context_to_str(pdb, &isid->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + rule = create_str("sid %s %s", 2, sid, ctx); + free(ctx); + if (!rule) { + rc = -1; + goto exit; + } + + rc = strs_add_at_index(strs, rule, i); + if (rc != 0) { + free(rule); + goto exit; + } + } + + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing sidcontext rules to policy.conf\n"); + } + + return rc; +} + +static int write_selinux_isid_rules_to_conf(FILE *out, struct policydb *pdb) +{ + return write_sid_context_rules_to_conf(out, pdb, selinux_sid_to_str, + SELINUX_SID_SZ); +} + +static int write_selinux_fsuse_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *fsuse; + const char *behavior; + char *name, *ctx; + int rc = 0; + + for (fsuse = pdb->ocontexts[5]; fsuse != NULL; fsuse = fsuse->next) { + switch (fsuse->v.behavior) { + case SECURITY_FS_USE_XATTR: behavior = "xattr"; break; + case SECURITY_FS_USE_TRANS: behavior = "trans"; break; + case SECURITY_FS_USE_TASK: behavior = "task"; break; + default: + sepol_log_err("Unknown fsuse behavior: %i", fsuse->v.behavior); + rc = -1; + goto exit; + } + + name = fsuse->u.name; + ctx = context_to_str(pdb, &fsuse->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "fs_use_%s %s %s;\n", behavior, name, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing fsuse rules to policy.conf\n"); + } + + return rc; +} + +static int write_genfscon_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct genfs *genfs; + struct ocontext *ocon; + struct strs *strs; + char *fstype, *name, *ctx; + uint32_t sclass; + const char *file_type; + int rc; + + rc = strs_init(&strs, 32); + if (rc != 0) { + goto exit; + } + + for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) { + for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) { + fstype = genfs->fstype; + name = ocon->u.name; + + sclass = ocon->v.sclass; + file_type = NULL; + if (sclass) { + const char *class_name = pdb->p_class_val_to_name[sclass-1]; + if (strcmp(class_name, "file") == 0) { + file_type = "--"; + } else if (strcmp(class_name, "dir") == 0) { + file_type = "-d"; + } else if (strcmp(class_name, "chr_file") == 0) { + file_type = "-c"; + } else if (strcmp(class_name, "blk_file") == 0) { + file_type = "-b"; + } else if (strcmp(class_name, "sock_file") == 0) { + file_type = "-s"; + } else if (strcmp(class_name, "fifo_file") == 0) { + file_type = "-p"; + } else if (strcmp(class_name, "lnk_file") == 0) { + file_type = "-l"; + } else { + rc = -1; + goto exit; + } + } + + ctx = context_to_str(pdb, &ocon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + if (file_type) { + rc = strs_create_and_add(strs, "genfscon %s \"%s\" %s %s", 4, + fstype, name, file_type, ctx); + } else { + rc = strs_create_and_add(strs, "genfscon %s \"%s\" %s", 3, + fstype, name, ctx); + } + free(ctx); + if (rc != 0) { + goto exit; + } + } + } + + strs_sort(strs); + strs_write_each(strs, out); + +exit: + strs_free_all(strs); + strs_destroy(&strs); + + if (rc != 0) { + sepol_log_err("Error writing genfscon rules to policy.conf\n"); + } + + return rc; +} + +static int write_selinux_port_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *portcon; + const char *protocol; + uint16_t low; + uint16_t high; + char low_high_str[44]; /* 2^64 <= 20 digits so "low-high" <= 44 chars */ + char *ctx; + int rc = 0; + + for (portcon = pdb->ocontexts[2]; portcon != NULL; portcon = portcon->next) { + switch (portcon->u.port.protocol) { + case IPPROTO_TCP: protocol = "tcp"; break; + case IPPROTO_UDP: protocol = "udp"; break; + case IPPROTO_DCCP: protocol = "dccp"; break; + case IPPROTO_SCTP: protocol = "sctp"; break; + default: + sepol_log_err("Unknown portcon protocol: %i", portcon->u.port.protocol); + rc = -1; + goto exit; + } + + low = portcon->u.port.low_port; + high = portcon->u.port.high_port; + if (low == high) { + rc = snprintf(low_high_str, 44, "%u", low); + } else { + rc = snprintf(low_high_str, 44, "%u-%u", low, high); + } + if (rc < 0 || rc >= 44) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &portcon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "portcon %s %s %s\n", protocol, low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing portcon rules to policy.conf\n"); + } + + return rc; +} + +static int write_selinux_netif_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *netif; + char *name, *ctx1, *ctx2; + int rc = 0; + + for (netif = pdb->ocontexts[3]; netif != NULL; netif = netif->next) { + name = netif->u.name; + ctx1 = context_to_str(pdb, &netif->context[0]); + if (!ctx1) { + rc = -1; + goto exit; + } + ctx2 = context_to_str(pdb, &netif->context[1]); + if (!ctx2) { + free(ctx1); + rc = -1; + goto exit; + } + + sepol_printf(out, "netifcon %s %s %s\n", name, ctx1, ctx2); + + free(ctx1); + free(ctx2); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing netifcon rules to policy.conf\n"); + } + + return rc; +} + +static int write_selinux_node_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *node; + char addr[INET_ADDRSTRLEN]; + char mask[INET_ADDRSTRLEN]; + char *ctx; + int rc = 0; + + for (node = pdb->ocontexts[4]; node != NULL; node = node->next) { + if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon address is invalid: %m"); + rc = -1; + goto exit; + } + + if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon mask is invalid: %m"); + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &node->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "nodecon %s %s %s\n", addr, mask, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing nodecon rules to policy.conf\n"); + } + + return rc; +} + + +static int write_selinux_node6_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *node6; + char addr[INET6_ADDRSTRLEN]; + char mask[INET6_ADDRSTRLEN]; + char *ctx; + int rc = 0; + + for (node6 = pdb->ocontexts[6]; node6 != NULL; node6 = node6->next) { + if (inet_ntop(AF_INET6, &node6->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon address is invalid: %m"); + rc = -1; + goto exit; + } + + if (inet_ntop(AF_INET6, &node6->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { + sepol_log_err("Nodecon mask is invalid: %m"); + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &node6->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "nodecon %s %s %s\n", addr, mask, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing nodecon rules to policy.conf\n"); + } + + return rc; +} + +static int write_selinux_ibpkey_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *ibpkeycon; + char subnet_prefix_str[INET6_ADDRSTRLEN]; + struct in6_addr subnet_prefix = IN6ADDR_ANY_INIT; + uint16_t low; + uint16_t high; + char low_high_str[44]; /* 2^64 <= 20 digits so "low-high" <= 44 chars */ + char *ctx; + int rc = 0; + + for (ibpkeycon = pdb->ocontexts[OCON_IBPKEY]; ibpkeycon != NULL; + ibpkeycon = ibpkeycon->next) { + memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix, + sizeof(ibpkeycon->u.ibpkey.subnet_prefix)); + + if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, + subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { + sepol_log_err("ibpkeycon address is invalid: %m"); + rc = -1; + goto exit; + } + + low = ibpkeycon->u.ibpkey.low_pkey; + high = ibpkeycon->u.ibpkey.high_pkey; + if (low == high) { + rc = snprintf(low_high_str, 44, "%u", low); + } else { + rc = snprintf(low_high_str, 44, "%u-%u", low, high); + } + if (rc < 0 || rc >= 44) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &ibpkeycon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "ibpkeycon %s %s %s\n", subnet_prefix_str, + low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing ibpkeycon rules to policy.conf\n"); + } + + return rc; +} + +static int write_selinux_ibendport_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *ibendportcon; + char port_str[4]; + char *ctx; + int rc = 0; + + for (ibendportcon = pdb->ocontexts[OCON_IBENDPORT]; + ibendportcon != NULL; ibendportcon = ibendportcon->next) { + rc = snprintf(port_str, 4, "%u", ibendportcon->u.ibendport.port); + if (rc < 0 || rc >= 4) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &ibendportcon->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "ibendportcon %s %s %s\n", ibendportcon->u.ibendport.dev_name, port_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing ibendportcon rules to policy.conf\n"); + } + + return rc; +} + +static int write_xen_isid_rules_to_conf(FILE *out, struct policydb *pdb) +{ + return write_sid_context_rules_to_conf(out, pdb, xen_sid_to_str, XEN_SID_SZ); +} + + +static int write_xen_pirq_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *pirq; + char pirq_str[21]; /* 2^64-1 <= 20 digits */ + char *ctx; + int rc = 0; + + for (pirq = pdb->ocontexts[1]; pirq != NULL; pirq = pirq->next) { + rc = snprintf(pirq_str, 21, "%i", pirq->u.pirq); + if (rc < 0 || rc >= 21) { + fprintf(stderr,"error1\n"); + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &pirq->context[0]); + if (!ctx) { + rc = -1; + fprintf(stderr,"error2\n"); + goto exit; + } + + sepol_printf(out, "pirqcon %s %s\n", pirq_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing pirqcon rules to policy.conf\n"); + } + + return rc; +} + +static int write_xen_ioport_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *ioport; + uint32_t low; + uint32_t high; + char low_high_str[40]; /* 2^64-1 <= 16 digits (hex) so low-high < 40 chars */ + char *ctx; + int rc = 0; + + for (ioport = pdb->ocontexts[2]; ioport != NULL; ioport = ioport->next) { + low = ioport->u.ioport.low_ioport; + high = ioport->u.ioport.high_ioport; + if (low == high) { + rc = snprintf(low_high_str, 40, "0x%x", low); + } else { + rc = snprintf(low_high_str, 40, "0x%x-0x%x", low, high); + } + if (rc < 0 || rc >= 40) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &ioport->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "ioportcon %s %s\n", low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing ioportcon rules to policy.conf\n"); + } + + return rc; +} + +static int write_xen_iomem_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *iomem; + uint64_t low; + uint64_t high; + char low_high_str[40]; /* 2^64-1 <= 16 digits (hex) so low-high < 40 chars */ + char *ctx; + int rc = 0; + + for (iomem = pdb->ocontexts[3]; iomem != NULL; iomem = iomem->next) { + low = iomem->u.iomem.low_iomem; + high = iomem->u.iomem.high_iomem; + if (low == high) { + rc = snprintf(low_high_str, 40, "0x%"PRIx64, low); + } else { + rc = snprintf(low_high_str, 40, "0x%"PRIx64"-0x%"PRIx64, low, high); + } + if (rc < 0 || rc >= 40) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &iomem->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "iomemcon %s %s\n", low_high_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing iomemcon rules to policy.conf\n"); + } + + return rc; +} + +static int write_xen_pcidevice_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *pcid; + char device_str[20]; /* 2^64-1 <= 16 digits (hex) so < 19 chars */ + char *ctx; + int rc = 0; + + for (pcid = pdb->ocontexts[4]; pcid != NULL; pcid = pcid->next) { + rc = snprintf(device_str, 20, "0x%lx", (unsigned long)pcid->u.device); + if (rc < 0 || rc >= 20) { + rc = -1; + goto exit; + } + + ctx = context_to_str(pdb, &pcid->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "pcidevicecon %s %s\n", device_str, ctx); + + free(ctx); + } + + rc = 0; + +exit: + if (rc != 0) { + sepol_log_err("Error writing pcidevicecon rules to policy.conf\n"); + } + + return rc; +} + +static int write_xen_devicetree_rules_to_conf(FILE *out, struct policydb *pdb) +{ + struct ocontext *dtree; + char *name, *ctx; + int rc = 0; + + for (dtree = pdb->ocontexts[5]; dtree != NULL; dtree = dtree->next) { + name = dtree->u.name; + ctx = context_to_str(pdb, &dtree->context[0]); + if (!ctx) { + rc = -1; + goto exit; + } + + sepol_printf(out, "devicetreecon \"%s\" %s\n", name, ctx); + + free(ctx); + } + +exit: + if (rc != 0) { + sepol_log_err("Error writing devicetreecon rules to policy.conf\n"); + } + + return rc; +} + +int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb) +{ + struct strs *mls_constraints = NULL; + struct strs *non_mls_constraints = NULL; + struct strs *mls_validatetrans = NULL; + struct strs *non_mls_validatetrans = NULL; + int rc = 0; + + rc = strs_init(&mls_constraints, 32); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&non_mls_constraints, 32); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&mls_validatetrans, 32); + if (rc != 0) { + goto exit; + } + + rc = strs_init(&non_mls_validatetrans, 32); + if (rc != 0) { + goto exit; + } + + if (pdb == NULL) { + sepol_log_err("No policy"); + rc = -1; + goto exit; + } + + if (pdb->policy_type != SEPOL_POLICY_KERN) { + sepol_log_err("Policy is not a kernel policy"); + rc = -1; + goto exit; + } + + if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { + /* + * For policy versions between 20 and 23, attributes exist in the policy, + * but only in the type_attr_map. This means that there are gaps in both + * the type_val_to_struct and p_type_val_to_name arrays and policy rules + * can refer to those gaps. + */ + sepol_log_err("Writing policy versions between 20 and 23 as a policy.conf is not supported"); + rc = -1; + goto exit; + } + + rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints); + if (rc != 0) { + goto exit; + } + + rc = validatetrans_rules_to_strs(pdb, mls_validatetrans, non_mls_validatetrans); + if (rc != 0) { + goto exit; + } + + rc = write_handle_unknown_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_class_decl_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_sid_decl_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_class_and_common_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_default_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_mls_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + strs_write_each(mls_constraints, out); + strs_write_each(mls_validatetrans, out); + + rc = write_polcap_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_attributes_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_attributes_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_boolean_decl_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_decl_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_alias_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_bounds_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_attribute_sets_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_type_permissive_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_avtab_to_conf(out, pdb, 0); + if (rc != 0) { + goto exit; + } + write_filename_trans_rules_to_conf(out, pdb); + + if (pdb->mls) { + rc = write_range_trans_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + } + + rc = write_cond_nodes_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_decl_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_transition_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_role_allow_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_user_decl_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + strs_write_each(non_mls_constraints, out); + strs_write_each(non_mls_validatetrans, out); + + rc = sort_ocontexts(pdb); + if (rc != 0) { + goto exit; + } + + if (pdb->target_platform == SEPOL_TARGET_SELINUX) { + rc = write_selinux_isid_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_fsuse_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_genfscon_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_port_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_netif_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_node_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_node6_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_ibpkey_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_selinux_ibendport_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + } else if (pdb->target_platform == SEPOL_TARGET_XEN) { + rc = write_xen_isid_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_genfscon_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_pirq_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_iomem_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_ioport_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_pcidevice_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + + rc = write_xen_devicetree_rules_to_conf(out, pdb); + if (rc != 0) { + goto exit; + } + } + +exit: + strs_free_all(mls_constraints); + strs_destroy(&mls_constraints); + strs_free_all(non_mls_constraints); + strs_destroy(&non_mls_constraints); + strs_free_all(mls_validatetrans); + strs_destroy(&mls_validatetrans); + strs_free_all(non_mls_validatetrans); + strs_destroy(&non_mls_validatetrans); + + return rc; +} diff --git a/kernel/libsepol/src/libsepol.map.in b/kernel/libsepol/src/libsepol.map.in new file mode 100644 index 00000000..844924fc --- /dev/null +++ b/kernel/libsepol/src/libsepol.map.in @@ -0,0 +1,291 @@ +LIBSEPOL_1.0 { + global: + cil_add_file; + cil_db_destroy; + cil_db_init; + cil_set_disable_dontaudit; + cil_set_disable_neverallow; + cil_set_handle_unknown; + cil_set_log_handler; + cil_set_log_level; + cil_set_preserve_tunables; + expand_module_avrules; + sepol_bool_clone; + sepol_bool_compare; + sepol_bool_compare2; + sepol_bool_count; + sepol_bool_create; + sepol_bool_exists; + sepol_bool_free; + sepol_bool_get_name; + sepol_bool_get_value; + sepol_bool_iterate; + sepol_bool_key_create; + sepol_bool_key_extract; + sepol_bool_key_free; + sepol_bool_key_unpack; + sepol_bool_query; + sepol_bool_set; + sepol_bool_set_name; + sepol_bool_set_value; + sepol_check_context; + sepol_context_check; + sepol_context_clone; + sepol_context_create; + sepol_context_free; + sepol_context_from_string; + sepol_context_get_mls; + sepol_context_get_role; + sepol_context_get_type; + sepol_context_get_user; + sepol_context_set_mls; + sepol_context_set_role; + sepol_context_set_type; + sepol_context_set_user; + sepol_context_to_string; + sepol_debug; + sepol_expand_module; + sepol_get_disable_dontaudit; + sepol_get_preserve_tunables; + sepol_handle_create; + sepol_handle_destroy; + sepol_ibendport_alloc_ibdev_name; + sepol_ibendport_clone; + sepol_ibendport_compare; + sepol_ibendport_compare2; + sepol_ibendport_count; + sepol_ibendport_create; + sepol_ibendport_exists; + sepol_ibendport_free; + sepol_ibendport_get_con; + sepol_ibendport_get_ibdev_name; + sepol_ibendport_get_port; + sepol_ibendport_iterate; + sepol_ibendport_key_create; + sepol_ibendport_key_extract; + sepol_ibendport_key_free; + sepol_ibendport_key_unpack; + sepol_ibendport_modify; + sepol_ibendport_query; + sepol_ibendport_set_con; + sepol_ibendport_set_ibdev_name; + sepol_ibendport_set_port; + sepol_ibpkey_clone; + sepol_ibpkey_compare; + sepol_ibpkey_compare2; + sepol_ibpkey_count; + sepol_ibpkey_create; + sepol_ibpkey_exists; + sepol_ibpkey_free; + sepol_ibpkey_get_con; + sepol_ibpkey_get_high; + sepol_ibpkey_get_low; + sepol_ibpkey_get_subnet_prefix; + sepol_ibpkey_get_subnet_prefix_bytes; + sepol_ibpkey_iterate; + sepol_ibpkey_key_create; + sepol_ibpkey_key_extract; + sepol_ibpkey_key_free; + sepol_ibpkey_key_unpack; + sepol_ibpkey_modify; + sepol_ibpkey_query; + sepol_ibpkey_set_con; + sepol_ibpkey_set_pkey; + sepol_ibpkey_set_range; + sepol_ibpkey_set_subnet_prefix; + sepol_ibpkey_set_subnet_prefix_bytes; + sepol_iface_clone; + sepol_iface_compare; + sepol_iface_compare2; + sepol_iface_count; + sepol_iface_create; + sepol_iface_exists; + sepol_iface_free; + sepol_iface_get_ifcon; + sepol_iface_get_msgcon; + sepol_iface_get_name; + sepol_iface_iterate; + sepol_iface_key_create; + sepol_iface_key_extract; + sepol_iface_key_free; + sepol_iface_key_unpack; + sepol_iface_modify; + sepol_iface_query; + sepol_iface_set_ifcon; + sepol_iface_set_msgcon; + sepol_iface_set_name; + sepol_link_modules; + sepol_link_packages; + sepol_mls_check; + sepol_mls_contains; + sepol_module_package_create; + sepol_module_package_free; + sepol_module_package_get_file_contexts; + sepol_module_package_get_file_contexts_len; + sepol_module_package_get_netfilter_contexts; + sepol_module_package_get_netfilter_contexts_len; + sepol_module_package_get_policy; + sepol_module_package_get_seusers; + sepol_module_package_get_seusers_len; + sepol_module_package_get_user_extra; + sepol_module_package_get_user_extra_len; + sepol_module_package_info; + sepol_module_package_read; + sepol_module_package_set_file_contexts; + sepol_module_package_set_netfilter_contexts; + sepol_module_package_set_seusers; + sepol_module_package_set_user_extra; + sepol_module_package_write; + sepol_msg_get_channel; + sepol_msg_get_fname; + sepol_msg_get_level; + sepol_msg_set_callback; + sepol_node_clone; + sepol_node_compare; + sepol_node_compare2; + sepol_node_count; + sepol_node_create; + sepol_node_exists; + sepol_node_free; + sepol_node_get_addr; + sepol_node_get_addr_bytes; + sepol_node_get_con; + sepol_node_get_mask; + sepol_node_get_mask_bytes; + sepol_node_get_proto; + sepol_node_get_proto_str; + sepol_node_iterate; + sepol_node_key_create; + sepol_node_key_extract; + sepol_node_key_free; + sepol_node_key_unpack; + sepol_node_modify; + sepol_node_query; + sepol_node_set_addr; + sepol_node_set_addr_bytes; + sepol_node_set_con; + sepol_node_set_mask; + sepol_node_set_mask_bytes; + sepol_node_set_proto; + sepol_policydb_compat_net; + sepol_policydb_create; + sepol_policydb_free; + sepol_policydb_from_image; + sepol_policydb_mls_enabled; + sepol_policydb_read; + sepol_policydb_set_handle_unknown; + sepol_policydb_set_target_platform; + sepol_policydb_set_typevers; + sepol_policydb_set_vers; + sepol_policydb_to_image; + sepol_policydb_write; + sepol_policy_file_create; + sepol_policy_file_free; + sepol_policy_file_get_len; + sepol_policy_file_set_fp; + sepol_policy_file_set_handle; + sepol_policy_file_set_mem; + sepol_policy_kern_vers_max; + sepol_policy_kern_vers_min; + sepol_port_clone; + sepol_port_compare; + sepol_port_compare2; + sepol_port_count; + sepol_port_create; + sepol_port_exists; + sepol_port_free; + sepol_port_get_con; + sepol_port_get_high; + sepol_port_get_low; + sepol_port_get_proto; + sepol_port_get_proto_str; + sepol_port_iterate; + sepol_port_key_create; + sepol_port_key_extract; + sepol_port_key_free; + sepol_port_key_unpack; + sepol_port_modify; + sepol_port_query; + sepol_port_set_con; + sepol_port_set_port; + sepol_port_set_proto; + sepol_port_set_range; + sepol_set_disable_dontaudit; + sepol_set_expand_consume_base; + sepol_set_policydb_from_file; + sepol_set_preserve_tunables; + sepol_user_add_role; + sepol_user_clone; + sepol_user_compare; + sepol_user_compare2; + sepol_user_count; + sepol_user_create; + sepol_user_del_role; + sepol_user_exists; + sepol_user_free; + sepol_user_get_mlslevel; + sepol_user_get_mlsrange; + sepol_user_get_name; + sepol_user_get_num_roles; + sepol_user_get_roles; + sepol_user_has_role; + sepol_user_iterate; + sepol_user_key_create; + sepol_user_key_extract; + sepol_user_key_free; + sepol_user_key_unpack; + sepol_user_modify; + sepol_user_query; + sepol_user_set_mlslevel; + sepol_user_set_mlsrange; + sepol_user_set_name; + sepol_user_set_roles; + local: *; +}; + +LIBSEPOL_1.1 { + global: + cil_build_policydb; + cil_compile; + cil_userprefixes_to_string; + cil_selinuxusers_to_string; + cil_filecons_to_string; + cil_set_target_platform; + cil_set_policy_version; + cil_set_mls; + cil_set_attrs_expand_generated; + cil_set_attrs_expand_size; + cil_set_multiple_decls; + cil_write_policy_conf; + sepol_ppfile_to_module_package; + sepol_module_package_to_cil; + sepol_module_policydb_to_cil; + sepol_kernel_policydb_to_cil; + sepol_kernel_policydb_to_conf; + sepol_polcap_getnum; + sepol_polcap_getname; +} LIBSEPOL_1.0; + +LIBSEPOL_3.0 { + global: + sepol_policydb_optimize; + cil_write_parse_ast; + cil_write_build_ast; + cil_write_resolve_ast; + cil_set_qualified_names; +} LIBSEPOL_1.1; + +LIBSEPOL_3.4 { + global: + sepol_av_perm_to_string; + sepol_change_sid; + sepol_compute_av; + sepol_compute_av_reason; + sepol_compute_av_reason_buffer; + sepol_context_to_sid; + sepol_member_sid; + sepol_sid_to_context; + sepol_string_to_av_perm; + sepol_string_to_security_class; + sepol_validate_transition_reason_buffer; +} LIBSEPOL_3.0; diff --git a/kernel/libsepol/src/libsepol.pc.in b/kernel/libsepol/src/libsepol.pc.in new file mode 100644 index 00000000..f807fec6 --- /dev/null +++ b/kernel/libsepol/src/libsepol.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ + +Name: libsepol +Description: SELinux policy library +Version: @VERSION@ +URL: http://userspace.selinuxproject.org/ +Libs: -L${libdir} -lsepol +Cflags: -I${includedir} diff --git a/kernel/libsepol/src/link.c b/kernel/libsepol/src/link.c new file mode 100644 index 00000000..789962b2 --- /dev/null +++ b/kernel/libsepol/src/link.c @@ -0,0 +1,2624 @@ +/* Authors: Karl MacMillan + * Joshua Brindle + * Jason Tang + * + * Copyright (C) 2004-2005 Tresys Technology, LLC + * Copyright (C) 2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +// #include +// #include +// #include +#include +// #include + +#include "debug.h" +#include "private.h" + +#undef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +typedef struct policy_module { + policydb_t *policy; + uint32_t num_decls; + uint32_t *map[SYM_NUM]; + uint32_t *avdecl_map; + uint32_t **perm_map; + uint32_t *perm_map_len; + + /* a pointer to within the base module's avrule_block chain to + * where this module's global now resides */ + avrule_block_t *base_global; +} policy_module_t; + +typedef struct link_state { + int verbose; + policydb_t *base; + avrule_block_t *last_avrule_block, *last_base_avrule_block; + uint32_t next_decl_id, current_decl_id; + + /* temporary variables, used during ksu_hashtab_map() calls */ + policy_module_t *cur; + char *cur_mod_name; + avrule_decl_t *dest_decl; + class_datum_t *src_class, *dest_class; + char *dest_class_name; + char dest_class_req; /* flag indicating the class was not declared */ + uint32_t symbol_num; + /* used to report the name of the module if dependency error occurs */ + policydb_t **decl_to_mod; + + /* error reporting fields */ + sepol_handle_t *handle; +} link_state_t; + +typedef struct missing_requirement { + uint32_t symbol_type; + uint32_t symbol_value; + uint32_t perm_value; +} missing_requirement_t; + +static const char * const symtab_names[SYM_NUM] = { + "common", "class", "role", "type/attribute", "user", + "bool", "level", "category" +}; + +/* Deallocates all elements within a module, but NOT the policydb_t + * structure within, as well as the pointer itself. */ +static void policy_module_destroy(policy_module_t * mod) +{ + unsigned int i; + if (mod == NULL) { + return; + } + for (i = 0; i < SYM_NUM; i++) { + free(mod->map[i]); + } + for (i = 0; mod->perm_map != NULL && i < mod->policy->p_classes.nprim; + i++) { + free(mod->perm_map[i]); + } + free(mod->perm_map); + free(mod->perm_map_len); + free(mod->avdecl_map); + free(mod); +} + +/***** functions that copy identifiers from a module to base *****/ + +/* Note: there is currently no scoping for permissions, which causes some + * strange side-effects. The current approach is this: + * + * a) perm is required and the class _and_ perm are declared in base: only add a mapping. + * b) perm is required and the class and perm are _not_ declared in base: simply add the permissions + * to the object class. This means that the requirements for the decl are the union of the permissions + * required for all decls, but who cares. + * c) perm is required, the class is declared in base, but the perm is not present. Nothing we can do + * here because we can't mark a single permission as required, so we bail with a requirement error + * _even_ if we are in an optional. + * + * A is correct behavior, b is wrong but not too bad, c is totall wrong for optionals. Fixing this requires + * a format change. + */ +static int permission_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *perm_id = key, *new_id = NULL; + perm_datum_t *perm, *new_perm = NULL, *dest_perm; + link_state_t *state = (link_state_t *) data; + + class_datum_t *src_class = state->src_class; + class_datum_t *dest_class = state->dest_class; + policy_module_t *mod = state->cur; + uint32_t sclassi = src_class->s.value - 1; + int ret; + + perm = (perm_datum_t *) datum; + dest_perm = hashtab_search(dest_class->permissions.table, perm_id); + if (dest_perm == NULL && dest_class->comdatum != NULL) { + dest_perm = + hashtab_search(dest_class->comdatum->permissions.table, + perm_id); + } + + if (dest_perm == NULL) { + /* If the object class was not declared in the base, add the perm + * to the object class. */ + if (state->dest_class_req) { + /* If the class was required (not declared), insert the new permission */ + new_id = strdup(perm_id); + if (new_id == NULL) { + ERR(state->handle, "Memory error"); + ret = SEPOL_ERR; + goto err; + } + new_perm = + (perm_datum_t *) calloc(1, sizeof(perm_datum_t)); + if (new_perm == NULL) { + ERR(state->handle, "Memory error"); + ret = SEPOL_ERR; + goto err; + } + ret = hashtab_insert(dest_class->permissions.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_perm); + if (ret) { + ERR(state->handle, + "could not insert permission into class"); + goto err; + } + new_perm->s.value = dest_class->permissions.nprim + 1; + dest_perm = new_perm; + } else { + /* this is case c from above */ + ERR(state->handle, + "Module %s depends on permission %s in class %s, not satisfied", + state->cur_mod_name, perm_id, + state->dest_class_name); + return SEPOL_EREQ; + } + } + + /* build the mapping for permissions encompassing this class. + * unlike symbols, the permission map translates between + * module permission bit to target permission bit. that bit + * may have originated from the class -or- it could be from + * the class's common parent.*/ + if (perm->s.value > mod->perm_map_len[sclassi]) { + uint32_t *newmap = calloc(perm->s.value, sizeof(*newmap)); + if (newmap == NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + if (mod->perm_map_len[sclassi] > 0) { + memcpy(newmap, mod->perm_map[sclassi], mod->perm_map_len[sclassi] * sizeof(*newmap)); + } + free(mod->perm_map[sclassi]); + mod->perm_map[sclassi] = newmap; + mod->perm_map_len[sclassi] = perm->s.value; + } + mod->perm_map[sclassi][perm->s.value - 1] = dest_perm->s.value; + + return 0; + err: + free(new_id); + free(new_perm); + return ret; +} + +static int class_copy_default_new_object(link_state_t *state, + class_datum_t *olddatum, + class_datum_t *newdatum) +{ + if (olddatum->default_user) { + if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { + ERR(state->handle, "Found conflicting default user definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_user = olddatum->default_user; + } + if (olddatum->default_role) { + if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { + ERR(state->handle, "Found conflicting default role definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_role = olddatum->default_role; + } + if (olddatum->default_type) { + if (newdatum->default_type && olddatum->default_type != newdatum->default_type) { + ERR(state->handle, "Found conflicting default type definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_type = olddatum->default_type; + } + if (olddatum->default_range) { + if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { + ERR(state->handle, "Found conflicting default range definitions"); + return SEPOL_ENOTSUP; + } + newdatum->default_range = olddatum->default_range; + } + return 0; +} + +static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id = key, *new_id = NULL; + class_datum_t *cladatum, *new_class = NULL; + link_state_t *state = (link_state_t *) data; + scope_datum_t *scope = NULL; + int ret; + + cladatum = (class_datum_t *) datum; + state->dest_class_req = 0; + + new_class = hashtab_search(state->base->p_classes.table, id); + /* If there is not an object class already in the base symtab that means + * that either a) a module is trying to declare a new object class (which + * the compiler should prevent) or b) an object class was required that is + * not in the base. + */ + if (new_class == NULL) { + scope = + hashtab_search(state->cur->policy->p_classes_scope.table, + id); + if (scope == NULL) { + ret = SEPOL_ERR; + goto err; + } + if (scope->scope == SCOPE_DECL) { + /* disallow declarations in modules */ + ERR(state->handle, + "%s: Modules may not yet declare new classes.", + state->cur_mod_name); + ret = SEPOL_ENOTSUP; + goto err; + } else { + /* It would be nice to error early here because the requirement is + * not met, but we cannot because the decl might be optional (in which + * case we should record the requirement so that it is just turned + * off). Note: this will break horribly if modules can declare object + * classes because the class numbers will be all wrong (i.e., they + * might be assigned in the order they were required rather than the + * current scheme which ensures correct numbering by ordering the + * declarations properly). This can't be fixed until some infrastructure + * for querying the object class numbers is in place. */ + state->dest_class_req = 1; + new_class = + (class_datum_t *) calloc(1, sizeof(class_datum_t)); + if (new_class == NULL) { + ERR(state->handle, "Memory error"); + ret = SEPOL_ERR; + goto err; + } + if (ksu_symtab_init + (&new_class->permissions, PERM_SYMTAB_SIZE)) { + ret = SEPOL_ERR; + goto err; + } + new_id = strdup(id); + if (new_id == NULL) { + ERR(state->handle, "Memory error"); + symtab_destroy(&new_class->permissions); + ret = SEPOL_ERR; + goto err; + } + ret = hashtab_insert(state->base->p_classes.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_class); + if (ret) { + ERR(state->handle, + "could not insert new class into symtab"); + symtab_destroy(&new_class->permissions); + goto err; + } + new_class->s.value = ++(state->base->p_classes.nprim); + } + } + + state->cur->map[SYM_CLASSES][cladatum->s.value - 1] = + new_class->s.value; + + /* copy permissions */ + state->src_class = cladatum; + state->dest_class = new_class; + state->dest_class_name = (char *)key; + + /* copy default new object rules */ + ret = class_copy_default_new_object(state, cladatum, new_class); + if (ret) + return ret; + + ret = + ksu_hashtab_map(cladatum->permissions.table, permission_copy_callback, + state); + if (ret != 0) { + return ret; + } + + return 0; + err: + free(new_class); + free(new_id); + return ret; +} + +static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id = key, *new_id = NULL; + role_datum_t *role, *base_role, *new_role = NULL; + link_state_t *state = (link_state_t *) data; + + role = (role_datum_t *) datum; + + base_role = hashtab_search(state->base->p_roles.table, id); + if (base_role != NULL) { + /* role already exists. check that it is what this + * module expected. duplicate declarations (e.g., two + * modules both declare role foo_r) is checked during + * scope_copy_callback(). */ + if (role->flavor == ROLE_ATTRIB + && base_role->flavor != ROLE_ATTRIB) { + ERR(state->handle, + "%s: Expected %s to be a role attribute, but it was already declared as a regular role.", + state->cur_mod_name, id); + return -1; + } else if (role->flavor != ROLE_ATTRIB + && base_role->flavor == ROLE_ATTRIB) { + ERR(state->handle, + "%s: Expected %s to be a regular role, but it was already declared as a role attribute.", + state->cur_mod_name, id); + return -1; + } + } else { + if (state->verbose) + INFO(state->handle, "copying role %s", id); + + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + + if ((new_role = + (role_datum_t *) malloc(sizeof(*new_role))) == NULL) { + goto cleanup; + } + role_datum_init(new_role); + + /* new_role's dominates, types and roles field will be copied + * during role_fix_callback() */ + new_role->flavor = role->flavor; + new_role->s.value = state->base->p_roles.nprim + 1; + + ret = hashtab_insert(state->base->p_roles.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_role); + if (ret) { + goto cleanup; + } + state->base->p_roles.nprim++; + base_role = new_role; + } + + if (state->dest_decl) { + new_id = NULL; + if ((new_role = malloc(sizeof(*new_role))) == NULL) { + goto cleanup; + } + role_datum_init(new_role); + new_role->flavor = base_role->flavor; + new_role->s.value = base_role->s.value; + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + if (hashtab_insert + (state->dest_decl->p_roles.table, new_id, new_role)) { + goto cleanup; + } + state->dest_decl->p_roles.nprim++; + } + + state->cur->map[SYM_ROLES][role->s.value - 1] = base_role->s.value; + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + role_datum_destroy(new_role); + free(new_id); + free(new_role); + return -1; +} + +/* Copy types and attributes from a module into the base module. The + * attributes are copied, but the types that make up this attribute + * are delayed type_fix_callback(). */ +static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id = key, *new_id = NULL; + type_datum_t *type, *base_type, *new_type = NULL; + link_state_t *state = (link_state_t *) data; + + type = (type_datum_t *) datum; + if ((type->flavor == TYPE_TYPE && !type->primary) + || type->flavor == TYPE_ALIAS) { + /* aliases are handled later, in alias_copy_callback() */ + return 0; + } + + base_type = hashtab_search(state->base->p_types.table, id); + if (base_type != NULL) { + /* type already exists. check that it is what this + * module expected. duplicate declarations (e.g., two + * modules both declare type foo_t) is checked during + * scope_copy_callback(). */ + if (type->flavor == TYPE_ATTRIB + && base_type->flavor != TYPE_ATTRIB) { + ERR(state->handle, + "%s: Expected %s to be an attribute, but it was already declared as a type.", + state->cur_mod_name, id); + return -1; + } else if (type->flavor != TYPE_ATTRIB + && base_type->flavor == TYPE_ATTRIB) { + ERR(state->handle, + "%s: Expected %s to be a type, but it was already declared as an attribute.", + state->cur_mod_name, id); + return -1; + } + + base_type->flags |= type->flags; + } else { + if (state->verbose) + INFO(state->handle, "copying type %s", id); + + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + + if ((new_type = + (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) { + goto cleanup; + } + new_type->primary = type->primary; + new_type->flags = type->flags; + new_type->flavor = type->flavor; + /* for attributes, the writing of new_type->types is + done in type_fix_callback() */ + + new_type->s.value = state->base->p_types.nprim + 1; + + ret = hashtab_insert(state->base->p_types.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_type); + if (ret) { + goto cleanup; + } + state->base->p_types.nprim++; + base_type = new_type; + } + + if (state->dest_decl) { + new_id = NULL; + if ((new_type = calloc(1, sizeof(*new_type))) == NULL) { + goto cleanup; + } + new_type->primary = type->primary; + new_type->flavor = type->flavor; + new_type->flags = type->flags; + new_type->s.value = base_type->s.value; + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + if (hashtab_insert + (state->dest_decl->p_types.table, new_id, new_type)) { + goto cleanup; + } + state->dest_decl->p_types.nprim++; + } + + state->cur->map[SYM_TYPES][type->s.value - 1] = base_type->s.value; + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + free(new_id); + free(new_type); + return -1; +} + +static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id = key, *new_id = NULL; + user_datum_t *user, *base_user, *new_user = NULL; + link_state_t *state = (link_state_t *) data; + + user = (user_datum_t *) datum; + + base_user = hashtab_search(state->base->p_users.table, id); + if (base_user == NULL) { + if (state->verbose) + INFO(state->handle, "copying user %s", id); + + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + + if ((new_user = + (user_datum_t *) malloc(sizeof(*new_user))) == NULL) { + goto cleanup; + } + user_datum_init(new_user); + /* new_users's roles and MLS fields will be copied during + user_fix_callback(). */ + + new_user->s.value = state->base->p_users.nprim + 1; + + ret = hashtab_insert(state->base->p_users.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_user); + if (ret) { + goto cleanup; + } + state->base->p_users.nprim++; + base_user = new_user; + } + + if (state->dest_decl) { + new_id = NULL; + if ((new_user = malloc(sizeof(*new_user))) == NULL) { + goto cleanup; + } + user_datum_init(new_user); + new_user->s.value = base_user->s.value; + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + if (hashtab_insert + (state->dest_decl->p_users.table, new_id, new_user)) { + goto cleanup; + } + state->dest_decl->p_users.nprim++; + } + + state->cur->map[SYM_USERS][user->s.value - 1] = base_user->s.value; + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + user_datum_destroy(new_user); + free(new_id); + free(new_user); + return -1; +} + +static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + int ret; + char *id = key, *new_id = NULL; + cond_bool_datum_t *booldatum, *base_bool, *new_bool = NULL; + link_state_t *state = (link_state_t *) data; + scope_datum_t *scope; + + booldatum = (cond_bool_datum_t *) datum; + + base_bool = hashtab_search(state->base->p_bools.table, id); + if (base_bool == NULL) { + if (state->verbose) + INFO(state->handle, "copying boolean %s", id); + + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + + if ((new_bool = + (cond_bool_datum_t *) malloc(sizeof(*new_bool))) == NULL) { + goto cleanup; + } + new_bool->s.value = state->base->p_bools.nprim + 1; + + ret = hashtab_insert(state->base->p_bools.table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_bool); + if (ret) { + goto cleanup; + } + state->base->p_bools.nprim++; + base_bool = new_bool; + base_bool->flags = booldatum->flags; + base_bool->state = booldatum->state; + } else if ((booldatum->flags & COND_BOOL_FLAGS_TUNABLE) != + (base_bool->flags & COND_BOOL_FLAGS_TUNABLE)) { + /* A mismatch between boolean/tunable declaration + * and usage(for example a boolean used in the + * tunable_policy() or vice versa). + * + * This is not allowed and bail out with errors */ + ERR(state->handle, + "%s: Mismatch between boolean/tunable definition " + "and usage for %s", state->cur_mod_name, id); + return -1; + } + + /* Get the scope info for this boolean to see if this is the declaration, + * if so set the state */ + scope = hashtab_search(state->cur->policy->p_bools_scope.table, id); + if (!scope) + return SEPOL_ERR; + if (scope->scope == SCOPE_DECL) { + base_bool->state = booldatum->state; + /* Only the declaration rather than requirement + * decides if it is a boolean or tunable. */ + base_bool->flags = booldatum->flags; + } + state->cur->map[SYM_BOOLS][booldatum->s.value - 1] = base_bool->s.value; + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + ksu_cond_destroy_bool(new_id, new_bool, NULL); + return -1; +} + +static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id = key; + level_datum_t *level, *base_level; + link_state_t *state = (link_state_t *) data; + scope_datum_t *scope; + + level = (level_datum_t *) datum; + + base_level = hashtab_search(state->base->p_levels.table, id); + if (!base_level) { + scope = + hashtab_search(state->cur->policy->p_sens_scope.table, id); + if (!scope) + return SEPOL_ERR; + if (scope->scope == SCOPE_DECL) { + /* disallow declarations in modules */ + ERR(state->handle, + "%s: Modules may not declare new sensitivities.", + state->cur_mod_name); + return SEPOL_ENOTSUP; + } else if (scope->scope == SCOPE_REQ) { + /* unmet requirement */ + ERR(state->handle, + "%s: Sensitivity %s not declared by base.", + state->cur_mod_name, id); + return SEPOL_ENOTSUP; + } else { + ERR(state->handle, + "%s: has an unknown scope: %d", + state->cur_mod_name, scope->scope); + return SEPOL_ENOTSUP; + } + } + + state->cur->map[SYM_LEVELS][level->level->sens - 1] = + base_level->level->sens; + + return 0; +} + +static int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id = key; + cat_datum_t *cat, *base_cat; + link_state_t *state = (link_state_t *) data; + scope_datum_t *scope; + + cat = (cat_datum_t *) datum; + + base_cat = hashtab_search(state->base->p_cats.table, id); + if (!base_cat) { + scope = hashtab_search(state->cur->policy->p_cat_scope.table, id); + if (!scope) + return SEPOL_ERR; + if (scope->scope == SCOPE_DECL) { + /* disallow declarations in modules */ + ERR(state->handle, + "%s: Modules may not declare new categories.", + state->cur_mod_name); + return SEPOL_ENOTSUP; + } else if (scope->scope == SCOPE_REQ) { + /* unmet requirement */ + ERR(state->handle, + "%s: Category %s not declared by base.", + state->cur_mod_name, id); + return SEPOL_ENOTSUP; + } else { + /* unknown scope? malformed policy? */ + ERR(state->handle, + "%s: has an unknown scope: %d", + state->cur_mod_name, scope->scope); + return SEPOL_ENOTSUP; + } + } + + state->cur->map[SYM_CATS][cat->s.value - 1] = base_cat->s.value; + + return 0; +} + +static int (*copy_callback_f[SYM_NUM]) (hashtab_key_t key, + hashtab_datum_t datum, void *datap) = { +NULL, class_copy_callback, role_copy_callback, type_copy_callback, + user_copy_callback, bool_copy_callback, sens_copy_callback, + cat_copy_callback}; + +/* + * The boundaries have to be copied after the types/roles/users are copied, + * because it refers hashtab to lookup destinated objects. + */ +static int type_bounds_copy_callback(hashtab_key_t key, + hashtab_datum_t datum, void *data) +{ + link_state_t *state = (link_state_t *) data; + type_datum_t *type = (type_datum_t *) datum; + type_datum_t *dest; + uint32_t bounds_val; + + if (!type->bounds) + return 0; + + bounds_val = state->cur->map[SYM_TYPES][type->bounds - 1]; + + dest = hashtab_search(state->base->p_types.table, key); + if (!dest) { + ERR(state->handle, + "Type lookup failed for %s", (char *)key); + return -1; + } + if (dest->bounds != 0 && dest->bounds != bounds_val) { + ERR(state->handle, + "Inconsistent boundary for %s", (char *)key); + return -1; + } + dest->bounds = bounds_val; + + return 0; +} + +static int role_bounds_copy_callback(hashtab_key_t key, + hashtab_datum_t datum, void *data) +{ + link_state_t *state = (link_state_t *) data; + role_datum_t *role = (role_datum_t *) datum; + role_datum_t *dest; + uint32_t bounds_val; + + if (!role->bounds) + return 0; + + bounds_val = state->cur->map[SYM_ROLES][role->bounds - 1]; + + dest = hashtab_search(state->base->p_roles.table, key); + if (!dest) { + ERR(state->handle, + "Role lookup failed for %s", (char *)key); + return -1; + } + if (dest->bounds != 0 && dest->bounds != bounds_val) { + ERR(state->handle, + "Inconsistent boundary for %s", (char *)key); + return -1; + } + dest->bounds = bounds_val; + + return 0; +} + +static int user_bounds_copy_callback(hashtab_key_t key, + hashtab_datum_t datum, void *data) +{ + link_state_t *state = (link_state_t *) data; + user_datum_t *user = (user_datum_t *) datum; + user_datum_t *dest; + uint32_t bounds_val; + + if (!user->bounds) + return 0; + + bounds_val = state->cur->map[SYM_USERS][user->bounds - 1]; + + dest = hashtab_search(state->base->p_users.table, key); + if (!dest) { + ERR(state->handle, + "User lookup failed for %s", (char *)key); + return -1; + } + if (dest->bounds != 0 && dest->bounds != bounds_val) { + ERR(state->handle, + "Inconsistent boundary for %s", (char *)key); + return -1; + } + dest->bounds = bounds_val; + + return 0; +} + +/* The aliases have to be copied after the types and attributes to be + * certain that the base symbol table will have the type that the + * alias refers. Otherwise, we won't be able to find the type value + * for the alias. We can't depend on the declaration ordering because + * of the hash table. + */ +static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id = key, *new_id = NULL, *target_id; + type_datum_t *type, *base_type, *new_type = NULL, *target_type; + link_state_t *state = (link_state_t *) data; + policy_module_t *mod = state->cur; + int primval; + + type = (type_datum_t *) datum; + /* there are 2 kinds of aliases. Ones with their own value (TYPE_ALIAS) + * and ones with the value of their primary (TYPE_TYPE && type->primary = 0) + */ + if (! + (type->flavor == TYPE_ALIAS + || (type->flavor == TYPE_TYPE && !type->primary))) { + /* ignore types and attributes -- they were handled in + * type_copy_callback() */ + return 0; + } + + if (type->flavor == TYPE_ALIAS) + primval = type->primary; + else + primval = type->s.value; + + target_id = mod->policy->p_type_val_to_name[primval - 1]; + target_type = hashtab_search(state->base->p_types.table, target_id); + if (target_type == NULL) { + ERR(state->handle, "%s: Could not find type %s for alias %s.", + state->cur_mod_name, target_id, id); + return -1; + } + + if (!strcmp(id, target_id)) { + ERR(state->handle, "%s: Self aliasing of %s.", + state->cur_mod_name, id); + return -1; + } + + target_type->flags |= type->flags; + + base_type = hashtab_search(state->base->p_types.table, id); + if (base_type == NULL) { + if (state->verbose) + INFO(state->handle, "copying alias %s", id); + + if ((new_type = + (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) { + goto cleanup; + } + /* the linked copy always has TYPE_ALIAS style aliases */ + new_type->primary = target_type->s.value; + new_type->flags = target_type->flags; + new_type->flavor = TYPE_ALIAS; + new_type->s.value = state->base->p_types.nprim + 1; + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + if (hashtab_insert + (state->base->p_types.table, new_id, new_type)) { + goto cleanup; + } + state->base->p_types.nprim++; + base_type = new_type; + } else { + + /* if this already exists and isn't an alias it was required by another module (or base) + * and inserted into the hashtable as a type, fix it up now */ + + if (base_type->flavor == TYPE_ALIAS) { + /* error checking */ + assert(base_type->primary == target_type->s.value); + assert(base_type->primary == + mod->map[SYM_TYPES][primval - 1]); + assert(mod->map[SYM_TYPES][type->s.value - 1] == + base_type->primary); + return 0; + } + + if (base_type->flavor == TYPE_ATTRIB) { + ERR(state->handle, + "%s is an alias of an attribute, not allowed", id); + return -1; + } + + base_type->flavor = TYPE_ALIAS; + base_type->primary = target_type->s.value; + base_type->flags |= target_type->flags; + + } + /* the aliases map points from its value to its primary so when this module + * references this type the value it gets back from the map is the primary */ + mod->map[SYM_TYPES][type->s.value - 1] = base_type->primary; + + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + free(new_id); + free(new_type); + return -1; +} + +/*********** callbacks that fix bitmaps ***********/ + +static int type_set_convert(type_set_t * types, type_set_t * dst, + policy_module_t * mod, link_state_t * state + __attribute__ ((unused))) +{ + unsigned int i; + ebitmap_node_t *tnode; + ebitmap_for_each_positive_bit(&types->types, tnode, i) { + assert(mod->map[SYM_TYPES][i]); + if (ksu_ebitmap_set_bit + (&dst->types, mod->map[SYM_TYPES][i] - 1, 1)) { + goto cleanup; + } + } + ebitmap_for_each_positive_bit(&types->negset, tnode, i) { + assert(mod->map[SYM_TYPES][i]); + if (ksu_ebitmap_set_bit + (&dst->negset, mod->map[SYM_TYPES][i] - 1, 1)) { + goto cleanup; + } + } + dst->flags = types->flags; + return 0; + + cleanup: + return -1; +} + +/* OR 2 typemaps together and at the same time map the src types to + * the correct values in the dst typeset. + */ +static int type_set_or_convert(type_set_t * types, type_set_t * dst, + policy_module_t * mod, link_state_t * state) +{ + type_set_t ts_tmp; + + type_set_init(&ts_tmp); + if (type_set_convert(types, &ts_tmp, mod, state) == -1) { + goto cleanup; + } + if (type_set_or_eq(dst, &ts_tmp)) { + goto cleanup; + } + type_set_destroy(&ts_tmp); + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + type_set_destroy(&ts_tmp); + return -1; +} + +static int role_set_or_convert(role_set_t * roles, role_set_t * dst, + policy_module_t * mod, link_state_t * state) +{ + unsigned int i; + ebitmap_t tmp; + ebitmap_node_t *rnode; + + ebitmap_init(&tmp); + ebitmap_for_each_positive_bit(&roles->roles, rnode, i) { + assert(mod->map[SYM_ROLES][i]); + if (ksu_ebitmap_set_bit + (&tmp, mod->map[SYM_ROLES][i] - 1, 1)) { + goto cleanup; + } + } + if (ebitmap_union(&dst->roles, &tmp)) { + goto cleanup; + } + dst->flags |= roles->flags; + ksu_ebitmap_destroy(&tmp); + return 0; + cleanup: + ERR(state->handle, "Out of memory!"); + ksu_ebitmap_destroy(&tmp); + return -1; +} + +static int mls_level_convert(mls_semantic_level_t * src, mls_semantic_level_t * dst, + policy_module_t * mod, link_state_t * state) +{ + mls_semantic_cat_t *src_cat, *new_cat; + + if (!mod->policy->mls) + return 0; + + /* Required not declared. */ + if (!src->sens) + return 0; + + assert(mod->map[SYM_LEVELS][src->sens - 1]); + dst->sens = mod->map[SYM_LEVELS][src->sens - 1]; + + for (src_cat = src->cat; src_cat; src_cat = src_cat->next) { + new_cat = + (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); + if (!new_cat) { + ERR(state->handle, "Out of memory"); + return -1; + } + mls_semantic_cat_init(new_cat); + + new_cat->next = dst->cat; + dst->cat = new_cat; + + assert(mod->map[SYM_CATS][src_cat->low - 1]); + dst->cat->low = mod->map[SYM_CATS][src_cat->low - 1]; + assert(mod->map[SYM_CATS][src_cat->high - 1]); + dst->cat->high = mod->map[SYM_CATS][src_cat->high - 1]; + } + + return 0; +} + +static int mls_range_convert(mls_semantic_range_t * src, mls_semantic_range_t * dst, + policy_module_t * mod, link_state_t * state) +{ + int ret; + ret = mls_level_convert(&src->level[0], &dst->level[0], mod, state); + if (ret) + return ret; + ret = mls_level_convert(&src->level[1], &dst->level[1], mod, state); + if (ret) + return ret; + return 0; +} + +static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + unsigned int i; + char *id = key; + role_datum_t *role, *dest_role = NULL; + link_state_t *state = (link_state_t *) data; + ebitmap_t e_tmp; + policy_module_t *mod = state->cur; + ebitmap_node_t *rnode; + hashtab_t role_tab; + + role = (role_datum_t *) datum; + if (state->dest_decl == NULL) + role_tab = state->base->p_roles.table; + else + role_tab = state->dest_decl->p_roles.table; + + dest_role = hashtab_search(role_tab, id); + assert(dest_role != NULL); + + if (state->verbose) { + INFO(state->handle, "fixing role %s", id); + } + + ebitmap_init(&e_tmp); + ebitmap_for_each_positive_bit(&role->dominates, rnode, i) { + assert(mod->map[SYM_ROLES][i]); + if (ksu_ebitmap_set_bit + (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { + goto cleanup; + } + } + if (ebitmap_union(&dest_role->dominates, &e_tmp)) { + goto cleanup; + } + if (type_set_or_convert(&role->types, &dest_role->types, mod, state)) { + goto cleanup; + } + ksu_ebitmap_destroy(&e_tmp); + + if (role->flavor == ROLE_ATTRIB) { + ebitmap_init(&e_tmp); + ebitmap_for_each_positive_bit(&role->roles, rnode, i) { + assert(mod->map[SYM_ROLES][i]); + if (ksu_ebitmap_set_bit + (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { + goto cleanup; + } + } + if (ebitmap_union(&dest_role->roles, &e_tmp)) { + goto cleanup; + } + ksu_ebitmap_destroy(&e_tmp); + } + + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + ksu_ebitmap_destroy(&e_tmp); + return -1; +} + +static int type_fix_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + unsigned int i; + char *id = key; + type_datum_t *type, *new_type = NULL; + link_state_t *state = (link_state_t *) data; + ebitmap_t e_tmp; + policy_module_t *mod = state->cur; + ebitmap_node_t *tnode; + symtab_t *typetab; + + type = (type_datum_t *) datum; + + if (state->dest_decl == NULL) + typetab = &state->base->p_types; + else + typetab = &state->dest_decl->p_types; + + /* only fix attributes */ + if (type->flavor != TYPE_ATTRIB) { + return 0; + } + + new_type = hashtab_search(typetab->table, id); + assert(new_type != NULL && new_type->flavor == TYPE_ATTRIB); + + if (state->verbose) { + INFO(state->handle, "fixing attribute %s", id); + } + + ebitmap_init(&e_tmp); + ebitmap_for_each_positive_bit(&type->types, tnode, i) { + assert(mod->map[SYM_TYPES][i]); + if (ksu_ebitmap_set_bit + (&e_tmp, mod->map[SYM_TYPES][i] - 1, 1)) { + goto cleanup; + } + } + if (ebitmap_union(&new_type->types, &e_tmp)) { + goto cleanup; + } + ksu_ebitmap_destroy(&e_tmp); + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + ksu_ebitmap_destroy(&e_tmp); + return -1; +} + +static int user_fix_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + char *id = key; + user_datum_t *user, *new_user = NULL; + link_state_t *state = (link_state_t *) data; + policy_module_t *mod = state->cur; + symtab_t *usertab; + + user = (user_datum_t *) datum; + + if (state->dest_decl == NULL) + usertab = &state->base->p_users; + else + usertab = &state->dest_decl->p_users; + + new_user = hashtab_search(usertab->table, id); + assert(new_user != NULL); + + if (state->verbose) { + INFO(state->handle, "fixing user %s", id); + } + + if (role_set_or_convert(&user->roles, &new_user->roles, mod, state)) { + goto cleanup; + } + + if (mls_range_convert(&user->range, &new_user->range, mod, state)) + goto cleanup; + + if (mls_level_convert(&user->dfltlevel, &new_user->dfltlevel, mod, state)) + goto cleanup; + + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + return -1; +} + +static int (*fix_callback_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, + void *datap) = { +NULL, NULL, role_fix_callback, type_fix_callback, user_fix_callback, + NULL, NULL, NULL}; + +/*********** functions that copy AV rules ***********/ + +static int copy_avrule_list(avrule_t * list, avrule_t ** dst, + policy_module_t * module, link_state_t * state) +{ + unsigned int i; + avrule_t *cur, *new_rule = NULL, *tail; + class_perm_node_t *cur_perm, *new_perm, *tail_perm = NULL; + + tail = *dst; + while (tail && tail->next) { + tail = tail->next; + } + + cur = list; + while (cur) { + if ((new_rule = (avrule_t *) malloc(sizeof(avrule_t))) == NULL) { + goto cleanup; + } + avrule_init(new_rule); + + new_rule->specified = cur->specified; + new_rule->flags = cur->flags; + if (type_set_convert + (&cur->stypes, &new_rule->stypes, module, state) == -1 + || type_set_convert(&cur->ttypes, &new_rule->ttypes, module, + state) == -1) { + goto cleanup; + } + + cur_perm = cur->perms; + tail_perm = NULL; + while (cur_perm) { + if ((new_perm = (class_perm_node_t *) + malloc(sizeof(class_perm_node_t))) == NULL) { + goto cleanup; + } + class_perm_node_init(new_perm); + + new_perm->tclass = + module->map[SYM_CLASSES][cur_perm->tclass - 1]; + assert(new_perm->tclass); + + if (new_rule->specified & AVRULE_AV) { + for (i = 0; + i < + module->perm_map_len[cur_perm->tclass - 1]; + i++) { + if (!(cur_perm->data & (UINT32_C(1) << i))) + continue; + new_perm->data |= + (UINT32_C(1) << + (module-> + perm_map[cur_perm->tclass - 1][i] - + 1)); + } + } else { + new_perm->data = + module->map[SYM_TYPES][cur_perm->data - 1]; + } + + if (new_rule->perms == NULL) { + new_rule->perms = new_perm; + } else { + assert(tail_perm); + tail_perm->next = new_perm; + } + tail_perm = new_perm; + cur_perm = cur_perm->next; + } + + if (cur->xperms) { + new_rule->xperms = calloc(1, sizeof(*new_rule->xperms)); + if (!new_rule->xperms) + goto cleanup; + memcpy(new_rule->xperms, cur->xperms, + sizeof(*new_rule->xperms)); + } + + new_rule->line = cur->line; + new_rule->source_line = cur->source_line; + if (cur->source_filename) { + new_rule->source_filename = strdup(cur->source_filename); + if (!new_rule->source_filename) + goto cleanup; + } + + cur = cur->next; + + if (*dst == NULL) { + *dst = new_rule; + } else { + tail->next = new_rule; + } + tail = new_rule; + } + + return 0; + cleanup: + ERR(state->handle, "Out of memory!"); + avrule_destroy(new_rule); + free(new_rule); + return -1; +} + +static int copy_role_trans_list(role_trans_rule_t * list, + role_trans_rule_t ** dst, + policy_module_t * module, link_state_t * state) +{ + role_trans_rule_t *cur, *new_rule = NULL, *tail; + unsigned int i; + ebitmap_node_t *cnode; + + cur = list; + tail = *dst; + while (tail && tail->next) { + tail = tail->next; + } + while (cur) { + if ((new_rule = + (role_trans_rule_t *) malloc(sizeof(role_trans_rule_t))) == + NULL) { + goto cleanup; + } + role_trans_rule_init(new_rule); + + if (role_set_or_convert + (&cur->roles, &new_rule->roles, module, state) + || type_set_or_convert(&cur->types, &new_rule->types, + module, state)) { + goto cleanup; + } + + ebitmap_for_each_positive_bit(&cur->classes, cnode, i) { + assert(module->map[SYM_CLASSES][i]); + if (ksu_ebitmap_set_bit(&new_rule->classes, + module-> + map[SYM_CLASSES][i] - 1, + 1)) { + goto cleanup; + } + } + + new_rule->new_role = module->map[SYM_ROLES][cur->new_role - 1]; + + if (*dst == NULL) { + *dst = new_rule; + } else { + tail->next = new_rule; + } + tail = new_rule; + cur = cur->next; + } + return 0; + cleanup: + ERR(state->handle, "Out of memory!"); + role_trans_rule_list_destroy(new_rule); + return -1; +} + +static int copy_role_allow_list(role_allow_rule_t * list, + role_allow_rule_t ** dst, + policy_module_t * module, link_state_t * state) +{ + role_allow_rule_t *cur, *new_rule = NULL, *tail; + + cur = list; + tail = *dst; + while (tail && tail->next) { + tail = tail->next; + } + + while (cur) { + if ((new_rule = + (role_allow_rule_t *) malloc(sizeof(role_allow_rule_t))) == + NULL) { + goto cleanup; + } + role_allow_rule_init(new_rule); + + if (role_set_or_convert + (&cur->roles, &new_rule->roles, module, state) + || role_set_or_convert(&cur->new_roles, + &new_rule->new_roles, module, + state)) { + goto cleanup; + } + if (*dst == NULL) { + *dst = new_rule; + } else { + tail->next = new_rule; + } + tail = new_rule; + cur = cur->next; + } + return 0; + cleanup: + ERR(state->handle, "Out of memory!"); + role_allow_rule_list_destroy(new_rule); + return -1; +} + +static int copy_filename_trans_list(filename_trans_rule_t * list, + filename_trans_rule_t ** dst, + policy_module_t * module, + link_state_t * state) +{ + filename_trans_rule_t *cur, *new_rule, *tail; + + cur = list; + tail = *dst; + while (tail && tail->next) + tail = tail->next; + + while (cur) { + new_rule = malloc(sizeof(*new_rule)); + if (!new_rule) + goto err; + + filename_trans_rule_init(new_rule); + + if (*dst == NULL) + *dst = new_rule; + else + tail->next = new_rule; + tail = new_rule; + + new_rule->name = strdup(cur->name); + if (!new_rule->name) + goto err; + + if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module, state) || + type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module, state)) + goto err; + + new_rule->tclass = module->map[SYM_CLASSES][cur->tclass - 1]; + new_rule->otype = module->map[SYM_TYPES][cur->otype - 1]; + new_rule->flags = cur->flags; + + cur = cur->next; + } + return 0; +err: + ERR(state->handle, "Out of memory!"); + return -1; +} + +static int copy_range_trans_list(range_trans_rule_t * rules, + range_trans_rule_t ** dst, + policy_module_t * mod, link_state_t * state) +{ + range_trans_rule_t *rule, *new_rule = NULL; + unsigned int i; + ebitmap_node_t *cnode; + + for (rule = rules; rule; rule = rule->next) { + new_rule = + (range_trans_rule_t *) malloc(sizeof(range_trans_rule_t)); + if (!new_rule) + goto cleanup; + + range_trans_rule_init(new_rule); + + new_rule->next = *dst; + *dst = new_rule; + + if (type_set_convert(&rule->stypes, &new_rule->stypes, + mod, state)) + goto cleanup; + + if (type_set_convert(&rule->ttypes, &new_rule->ttypes, + mod, state)) + goto cleanup; + + ebitmap_for_each_positive_bit(&rule->tclasses, cnode, i) { + assert(mod->map[SYM_CLASSES][i]); + if (ksu_ebitmap_set_bit + (&new_rule->tclasses, + mod->map[SYM_CLASSES][i] - 1, 1)) { + goto cleanup; + } + } + + if (mls_range_convert(&rule->trange, &new_rule->trange, mod, state)) + goto cleanup; + } + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + range_trans_rule_list_destroy(new_rule); + return -1; +} + +static int copy_cond_list(cond_node_t * list, cond_node_t ** dst, + policy_module_t * module, link_state_t * state) +{ + unsigned i; + cond_node_t *cur, *new_node = NULL, *tail; + cond_expr_t *cur_expr; + tail = *dst; + while (tail && tail->next) + tail = tail->next; + + cur = list; + while (cur) { + new_node = (cond_node_t *) malloc(sizeof(cond_node_t)); + if (!new_node) { + goto cleanup; + } + memset(new_node, 0, sizeof(cond_node_t)); + + new_node->cur_state = cur->cur_state; + new_node->expr = cond_copy_expr(cur->expr); + if (!new_node->expr) + goto cleanup; + /* go back through and remap the expression */ + for (cur_expr = new_node->expr; cur_expr != NULL; + cur_expr = cur_expr->next) { + /* expression nodes don't have a bool value of 0 - don't map them */ + if (cur_expr->expr_type != COND_BOOL) + continue; + assert(module->map[SYM_BOOLS][cur_expr->bool - 1] != 0); + cur_expr->bool = + module->map[SYM_BOOLS][cur_expr->bool - 1]; + } + new_node->nbools = cur->nbools; + /* FIXME should COND_MAX_BOOLS be used here? */ + for (i = 0; i < min(cur->nbools, COND_MAX_BOOLS); i++) { + uint32_t remapped_id = + module->map[SYM_BOOLS][cur->bool_ids[i] - 1]; + assert(remapped_id != 0); + new_node->bool_ids[i] = remapped_id; + } + new_node->expr_pre_comp = cur->expr_pre_comp; + + if (copy_avrule_list + (cur->avtrue_list, &new_node->avtrue_list, module, state) + || copy_avrule_list(cur->avfalse_list, + &new_node->avfalse_list, module, + state)) { + goto cleanup; + } + + if (*dst == NULL) { + *dst = new_node; + } else { + tail->next = new_node; + } + tail = new_node; + cur = cur->next; + } + return 0; + cleanup: + ERR(state->handle, "Out of memory!"); + cond_node_destroy(new_node); + free(new_node); + return -1; + +} + +/*********** functions that copy avrule_decls from module to base ***********/ + +static int copy_identifiers(link_state_t * state, symtab_t * src_symtab, + avrule_decl_t * dest_decl) +{ + int i, ret; + + state->dest_decl = dest_decl; + for (i = 0; i < SYM_NUM; i++) { + if (copy_callback_f[i] != NULL) { + ret = + ksu_hashtab_map(src_symtab[i].table, copy_callback_f[i], + state); + if (ret) { + return ret; + } + } + } + + if (ksu_hashtab_map(src_symtab[SYM_TYPES].table, + type_bounds_copy_callback, state)) + return -1; + + if (ksu_hashtab_map(src_symtab[SYM_TYPES].table, + alias_copy_callback, state)) + return -1; + + if (ksu_hashtab_map(src_symtab[SYM_ROLES].table, + role_bounds_copy_callback, state)) + return -1; + + if (ksu_hashtab_map(src_symtab[SYM_USERS].table, + user_bounds_copy_callback, state)) + return -1; + + /* then fix bitmaps associated with those newly copied identifiers */ + for (i = 0; i < SYM_NUM; i++) { + if (fix_callback_f[i] != NULL && + ksu_hashtab_map(src_symtab[i].table, fix_callback_f[i], + state)) { + return -1; + } + } + return 0; +} + +static int copy_scope_index(scope_index_t * src, scope_index_t * dest, + policy_module_t * module, link_state_t * state) +{ + unsigned int i, j; + uint32_t largest_mapped_class_value = 0; + ebitmap_node_t *node; + /* copy the scoping information for this avrule decl block */ + for (i = 0; i < SYM_NUM; i++) { + ebitmap_t *srcmap = src->scope + i; + ebitmap_t *destmap = dest->scope + i; + if (copy_callback_f[i] == NULL) { + continue; + } + ebitmap_for_each_positive_bit(srcmap, node, j) { + assert(module->map[i][j] != 0); + if (ksu_ebitmap_set_bit + (destmap, module->map[i][j] - 1, 1) != 0) { + + goto cleanup; + } + if (i == SYM_CLASSES && + largest_mapped_class_value < + module->map[SYM_CLASSES][j]) { + largest_mapped_class_value = + module->map[SYM_CLASSES][j]; + } + } + } + + /* next copy the enabled permissions data */ + if ((dest->class_perms_map = calloc(largest_mapped_class_value, + sizeof(*dest->class_perms_map))) == NULL) { + goto cleanup; + } + dest->class_perms_len = largest_mapped_class_value; + for (i = 0; i < src->class_perms_len; i++) { + ebitmap_t *srcmap = src->class_perms_map + i; + ebitmap_t *destmap = + dest->class_perms_map + module->map[SYM_CLASSES][i] - 1; + ebitmap_for_each_positive_bit(srcmap, node, j) { + if (ksu_ebitmap_set_bit(destmap, module->perm_map[i][j] - 1, + 1)) { + goto cleanup; + } + } + } + + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + return -1; +} + +static int copy_avrule_decl(link_state_t * state, policy_module_t * module, + avrule_decl_t * src_decl, avrule_decl_t * dest_decl) +{ + int ret; + + /* copy all of the RBAC and TE rules */ + if (copy_avrule_list + (src_decl->avrules, &dest_decl->avrules, module, state) == -1 + || copy_role_trans_list(src_decl->role_tr_rules, + &dest_decl->role_tr_rules, module, + state) == -1 + || copy_role_allow_list(src_decl->role_allow_rules, + &dest_decl->role_allow_rules, module, + state) == -1 + || copy_cond_list(src_decl->cond_list, &dest_decl->cond_list, + module, state) == -1) { + return -1; + } + + if (copy_filename_trans_list(src_decl->filename_trans_rules, + &dest_decl->filename_trans_rules, + module, state)) + return -1; + + if (copy_range_trans_list(src_decl->range_tr_rules, + &dest_decl->range_tr_rules, module, state)) + return -1; + + /* finally copy any identifiers local to this declaration */ + ret = copy_identifiers(state, src_decl->symtab, dest_decl); + if (ret < 0) { + return ret; + } + + /* then copy required and declared scope indices here */ + if (copy_scope_index(&src_decl->required, &dest_decl->required, + module, state) == -1 || + copy_scope_index(&src_decl->declared, &dest_decl->declared, + module, state) == -1) { + return -1; + } + + return 0; +} + +static int copy_avrule_block(link_state_t * state, policy_module_t * module, + avrule_block_t * block) +{ + avrule_block_t *new_block = avrule_block_create(); + avrule_decl_t *decl, *last_decl = NULL; + int ret; + + if (new_block == NULL) { + ERR(state->handle, "Out of memory!"); + ret = -1; + goto cleanup; + } + + new_block->flags = block->flags; + + for (decl = block->branch_list; decl != NULL; decl = decl->next) { + avrule_decl_t *new_decl = + avrule_decl_create(state->next_decl_id); + if (new_decl == NULL) { + ERR(state->handle, "Out of memory!"); + ret = -1; + goto cleanup; + } + + if (module->policy->name != NULL) { + new_decl->module_name = strdup(module->policy->name); + if (new_decl->module_name == NULL) { + ERR(state->handle, "Out of memory"); + avrule_decl_destroy(new_decl); + ret = -1; + goto cleanup; + } + } + + if (last_decl == NULL) { + new_block->branch_list = new_decl; + } else { + last_decl->next = new_decl; + } + last_decl = new_decl; + state->base->decl_val_to_struct[state->next_decl_id - 1] = + new_decl; + state->decl_to_mod[state->next_decl_id] = module->policy; + + module->avdecl_map[decl->decl_id] = new_decl->decl_id; + + ret = copy_avrule_decl(state, module, decl, new_decl); + if (ret) { + avrule_decl_destroy(new_decl); + goto cleanup; + } + + state->next_decl_id++; + } + state->last_avrule_block->next = new_block; + state->last_avrule_block = new_block; + return 0; + + cleanup: + avrule_block_list_destroy(new_block); + return ret; +} + +static int scope_copy_callback(hashtab_key_t key, hashtab_datum_t datum, + void *data) +{ + unsigned int i; + int ret; + char *id = key, *new_id = NULL; + scope_datum_t *scope, *base_scope; + link_state_t *state = (link_state_t *) data; + uint32_t symbol_num = state->symbol_num; + uint32_t *avdecl_map = state->cur->avdecl_map; + + scope = (scope_datum_t *) datum; + + /* check if the base already has a scope entry */ + base_scope = hashtab_search(state->base->scope[symbol_num].table, id); + if (base_scope == NULL) { + scope_datum_t *new_scope; + if ((new_id = strdup(id)) == NULL) { + goto cleanup; + } + + if ((new_scope = + (scope_datum_t *) calloc(1, sizeof(*new_scope))) == NULL) { + free(new_id); + goto cleanup; + } + ret = hashtab_insert(state->base->scope[symbol_num].table, + (hashtab_key_t) new_id, + (hashtab_datum_t) new_scope); + if (ret) { + free(new_id); + free(new_scope); + goto cleanup; + } + new_scope->scope = SCOPE_REQ; /* this is reset further down */ + base_scope = new_scope; + } + if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_DECL) { + /* this module declared symbol, so overwrite the old + * list with the new decl ids */ + base_scope->scope = SCOPE_DECL; + free(base_scope->decl_ids); + base_scope->decl_ids = NULL; + base_scope->decl_ids_len = 0; + for (i = 0; i < scope->decl_ids_len; i++) { + if (add_i_to_a(avdecl_map[scope->decl_ids[i]], + &base_scope->decl_ids_len, + &base_scope->decl_ids) == -1) { + goto cleanup; + } + } + } else if (base_scope->scope == SCOPE_DECL && scope->scope == SCOPE_REQ) { + /* this module depended on a symbol that now exists, + * so don't do anything */ + } else if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_REQ) { + /* symbol is still required, so add to the list */ + for (i = 0; i < scope->decl_ids_len; i++) { + if (add_i_to_a(avdecl_map[scope->decl_ids[i]], + &base_scope->decl_ids_len, + &base_scope->decl_ids) == -1) { + goto cleanup; + } + } + } else { + /* this module declared a symbol, and it was already + * declared. only roles and users may be multiply + * declared; for all others this is an error. */ + if (symbol_num != SYM_ROLES && symbol_num != SYM_USERS) { + ERR(state->handle, + "%s: Duplicate declaration in module: %s %s", + state->cur_mod_name, + symtab_names[state->symbol_num], id); + return -1; + } + for (i = 0; i < scope->decl_ids_len; i++) { + if (add_i_to_a(avdecl_map[scope->decl_ids[i]], + &base_scope->decl_ids_len, + &base_scope->decl_ids) == -1) { + goto cleanup; + } + } + } + return 0; + + cleanup: + ERR(state->handle, "Out of memory!"); + return -1; +} + +/* Copy a module over to a base, remapping all values within. After + * all identifiers and rules are done, copy the scoping information. + * This is when it checks for duplicate declarations. */ +static int copy_module(link_state_t * state, policy_module_t * module) +{ + int i, ret; + avrule_block_t *cur; + state->cur = module; + state->cur_mod_name = module->policy->name; + + /* first copy all of the identifiers */ + ret = copy_identifiers(state, module->policy->symtab, NULL); + if (ret) { + return ret; + } + + /* next copy all of the avrule blocks */ + for (cur = module->policy->global; cur != NULL; cur = cur->next) { + ret = copy_avrule_block(state, module, cur); + if (ret) { + return ret; + } + } + + /* then copy the scoping tables */ + for (i = 0; i < SYM_NUM; i++) { + state->symbol_num = i; + if (ksu_hashtab_map + (module->policy->scope[i].table, scope_copy_callback, + state)) { + return -1; + } + } + + return 0; +} + +/***** functions that check requirements and enable blocks in a module ******/ + +/* borrowed from checkpolicy.c */ + +struct find_perm_arg { + unsigned int valuep; + hashtab_key_t key; +}; + +static int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *varg) +{ + + struct find_perm_arg *arg = varg; + + perm_datum_t *perdatum = (perm_datum_t *) datum; + if (arg->valuep == perdatum->s.value) { + arg->key = key; + return 1; + } + + return 0; +} + +/* Check if the requirements are met for a single declaration. If all + * are met return 1. For the first requirement found to be missing, + * if 'missing_sym_num' and 'missing_value' are both not NULL then + * write to them the symbol number and value for the missing + * declaration. Then return 0 to indicate a missing declaration. + * Note that if a declaration had no requirement at all (e.g., an ELSE + * block) this returns 1. */ +static int is_decl_requires_met(link_state_t * state, + avrule_decl_t * decl, + struct missing_requirement *req) +{ + /* (This algorithm is very unoptimized. It performs many + * redundant checks. A very obvious improvement is to cache + * which symbols have been verified, so that they do not need + * to be re-checked.) */ + unsigned int i, j; + ebitmap_t *bitmap; + char *id, *perm_id; + policydb_t *pol = state->base; + ebitmap_node_t *node; + + /* check that all symbols have been satisfied */ + for (i = 0; i < SYM_NUM; i++) { + if (i == SYM_CLASSES) { + /* classes will be checked during permissions + * checking phase below */ + continue; + } + bitmap = &decl->required.scope[i]; + ebitmap_for_each_positive_bit(bitmap, node, j) { + /* check base's scope table */ + id = pol->sym_val_to_name[i][j]; + if (!is_id_enabled(id, state->base, i)) { + /* this symbol was not found */ + if (req != NULL) { + req->symbol_type = i; + req->symbol_value = j + 1; + } + return 0; + } + } + } + /* check that all classes and permissions have been satisfied */ + for (i = 0; i < decl->required.class_perms_len; i++) { + + bitmap = decl->required.class_perms_map + i; + ebitmap_for_each_positive_bit(bitmap, node, j) { + struct find_perm_arg fparg; + class_datum_t *cladatum; + uint32_t perm_value = j + 1; + int rc; + scope_datum_t *scope; + + id = pol->p_class_val_to_name[i]; + cladatum = pol->class_val_to_struct[i]; + + scope = + hashtab_search(state->base->p_classes_scope.table, + id); + if (scope == NULL) { + ERR(state->handle, + "Could not find scope information for class %s", + id); + return -1; + } + + fparg.valuep = perm_value; + fparg.key = NULL; + + (void)ksu_hashtab_map(cladatum->permissions.table, find_perm, + &fparg); + if (fparg.key == NULL && cladatum->comdatum != NULL) { + rc = ksu_hashtab_map(cladatum->comdatum->permissions.table, + find_perm, &fparg); + assert(rc == 1); + } + perm_id = fparg.key; + + assert(perm_id != NULL); + if (!is_perm_enabled(id, perm_id, state->base)) { + if (req != NULL) { + req->symbol_type = SYM_CLASSES; + req->symbol_value = i + 1; + req->perm_value = perm_value; + } + return 0; + } + } + } + + /* all requirements have been met */ + return 1; +} + +static int debug_requirements(link_state_t * state, policydb_t * p) +{ + int ret; + avrule_block_t *cur; + missing_requirement_t req; + memset(&req, 0, sizeof(req)); + + for (cur = p->global; cur != NULL; cur = cur->next) { + if (cur->enabled != NULL) + continue; + + ret = is_decl_requires_met(state, cur->branch_list, &req); + if (ret < 0) { + return ret; + } else if (ret == 0) { + const char *mod_name = cur->branch_list->module_name ? + cur->branch_list->module_name : "BASE"; + if (req.symbol_type == SYM_CLASSES) { + struct find_perm_arg fparg; + + class_datum_t *cladatum; + cladatum = p->class_val_to_struct[req.symbol_value - 1]; + + fparg.valuep = req.perm_value; + fparg.key = NULL; + (void)ksu_hashtab_map(cladatum->permissions.table, + find_perm, &fparg); + + if (cur->flags & AVRULE_OPTIONAL) { + ERR(state->handle, + "%s[%d]'s optional requirements were not met: class %s, permission %s", + mod_name, cur->branch_list->decl_id, + p->p_class_val_to_name[req.symbol_value - 1], + fparg.key); + } else { + ERR(state->handle, + "%s[%d]'s global requirements were not met: class %s, permission %s", + mod_name, cur->branch_list->decl_id, + p->p_class_val_to_name[req.symbol_value - 1], + fparg.key); + } + } else { + if (cur->flags & AVRULE_OPTIONAL) { + ERR(state->handle, + "%s[%d]'s optional requirements were not met: %s %s", + mod_name, cur->branch_list->decl_id, + symtab_names[req.symbol_type], + p->sym_val_to_name[req. + symbol_type][req. + symbol_value + - + 1]); + } else { + ERR(state->handle, + "%s[%d]'s global requirements were not met: %s %s", + mod_name, cur->branch_list->decl_id, + symtab_names[req.symbol_type], + p->sym_val_to_name[req. + symbol_type][req. + symbol_value + - + 1]); + } + } + } + } + return 0; +} + +static void print_missing_requirements(link_state_t * state, + avrule_block_t * cur, + missing_requirement_t * req) +{ + policydb_t *p = state->base; + const char *mod_name = cur->branch_list->module_name ? + cur->branch_list->module_name : "BASE"; + + if (req->symbol_type == SYM_CLASSES) { + + struct find_perm_arg fparg; + + class_datum_t *cladatum; + cladatum = p->class_val_to_struct[req->symbol_value - 1]; + + fparg.valuep = req->perm_value; + fparg.key = NULL; + (void)ksu_hashtab_map(cladatum->permissions.table, find_perm, &fparg); + + ERR(state->handle, + "%s's global requirements were not met: class %s, permission %s", + mod_name, + p->p_class_val_to_name[req->symbol_value - 1], fparg.key); + } else { + ERR(state->handle, + "%s's global requirements were not met: %s %s", + mod_name, + symtab_names[req->symbol_type], + p->sym_val_to_name[req->symbol_type][req->symbol_value - 1]); + } +} + +/* Enable all of the avrule_decl blocks for the policy. This simple + * algorithm is the following: + * + * 1) Enable all of the non-else avrule_decls for all blocks. + * 2) Iterate through the non-else decls looking for decls whose requirements + * are not met. + * 2a) If the decl is non-optional, return immediately with an error. + * 2b) If the decl is optional, disable the block and mark changed = 1 + * 3) If changed == 1 goto 2. + * 4) Iterate through all blocks looking for those that have no enabled + * decl. If the block has an else decl, enable. + * + * This will correctly handle all dependencies, including mutual and + * circular. The only downside is that it is slow. + */ +static int enable_avrules(link_state_t * state, policydb_t * pol) +{ + int changed = 1; + avrule_block_t *block; + avrule_decl_t *decl; + missing_requirement_t req; + int ret = 0, rc; + + if (state->verbose) { + INFO(state->handle, "Determining which avrules to enable."); + } + + /* 1) enable all of the non-else blocks */ + for (block = pol->global; block != NULL; block = block->next) { + block->enabled = block->branch_list; + block->enabled->enabled = 1; + for (decl = block->branch_list->next; decl != NULL; + decl = decl->next) + decl->enabled = 0; + } + + /* 2) Iterate */ + while (changed) { + changed = 0; + for (block = pol->global; block != NULL; block = block->next) { + if (block->enabled == NULL) { + continue; + } + decl = block->branch_list; + if (state->verbose) { + const char *mod_name = decl->module_name ? + decl->module_name : "BASE"; + INFO(state->handle, "check module %s decl %d", + mod_name, decl->decl_id); + } + rc = is_decl_requires_met(state, decl, &req); + if (rc < 0) { + ret = SEPOL_ERR; + goto out; + } else if (rc == 0) { + decl->enabled = 0; + block->enabled = NULL; + changed = 1; + if (!(block->flags & AVRULE_OPTIONAL)) { + print_missing_requirements(state, block, + &req); + ret = SEPOL_EREQ; + goto out; + } + } + } + } + + /* 4) else handling + * + * Iterate through all of the blocks skipping the first (which is the + * global block, is required to be present, and cannot have an else). + * If the block is disabled and has an else decl, enable that. + * + * This code assumes that the second block in the branch list is the else + * block. This is currently supported by the compiler. + */ + for (block = pol->global->next; block != NULL; block = block->next) { + if (block->enabled == NULL) { + if (block->branch_list->next != NULL) { + block->enabled = block->branch_list->next; + block->branch_list->next->enabled = 1; + } + } + } + + out: + if (state->verbose) + debug_requirements(state, pol); + + return ret; +} + +/*********** the main linking functions ***********/ + +/* Given a module's policy, normalize all conditional expressions + * within. Return 0 on success, -1 on error. */ +static int cond_normalize(policydb_t * p) +{ + avrule_block_t *block; + for (block = p->global; block != NULL; block = block->next) { + avrule_decl_t *decl; + for (decl = block->branch_list; decl != NULL; decl = decl->next) { + cond_list_t *cond = decl->cond_list; + while (cond) { + if (cond_normalize_expr(p, cond) < 0) + return -1; + cond = cond->next; + } + } + } + return 0; +} + +/* Allocate space for the various remapping arrays. */ +static int prepare_module(link_state_t * state, policy_module_t * module) +{ + int i; + uint32_t items, num_decls = 0; + avrule_block_t *cur; + + /* allocate the maps */ + for (i = 0; i < SYM_NUM; i++) { + items = module->policy->symtab[i].nprim; + if ((module->map[i] = + (uint32_t *) calloc(items, + sizeof(*module->map[i]))) == NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + } + + /* allocate the permissions remap here */ + items = module->policy->p_classes.nprim; + if ((module->perm_map_len = + calloc(items, sizeof(*module->perm_map_len))) == NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + if ((module->perm_map = + calloc(items, sizeof(*module->perm_map))) == NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + /* allocate a map for avrule_decls */ + for (cur = module->policy->global; cur != NULL; cur = cur->next) { + avrule_decl_t *decl; + for (decl = cur->branch_list; decl != NULL; decl = decl->next) { + if (decl->decl_id > num_decls) { + num_decls = decl->decl_id; + } + } + } + num_decls++; + if ((module->avdecl_map = calloc(num_decls, sizeof(uint32_t))) == NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + module->num_decls = num_decls; + + /* normalize conditionals within */ + if (cond_normalize(module->policy) < 0) { + ERR(state->handle, + "Error while normalizing conditionals within the module %s.", + module->policy->name); + return -1; + } + return 0; +} + +static int prepare_base(link_state_t * state, uint32_t num_mod_decls) +{ + avrule_block_t *cur = state->base->global; + assert(cur != NULL); + state->next_decl_id = 0; + + /* iterate through all of the declarations in the base, to + determine what the next decl_id should be */ + while (cur != NULL) { + avrule_decl_t *decl; + for (decl = cur->branch_list; decl != NULL; decl = decl->next) { + if (decl->decl_id > state->next_decl_id) { + state->next_decl_id = decl->decl_id; + } + } + state->last_avrule_block = cur; + cur = cur->next; + } + state->last_base_avrule_block = state->last_avrule_block; + state->next_decl_id++; + + /* allocate the table mapping from base's decl_id to its + * avrule_decls and set the initial mappings */ + free(state->base->decl_val_to_struct); + if ((state->base->decl_val_to_struct = + calloc(state->next_decl_id + num_mod_decls, + sizeof(*(state->base->decl_val_to_struct)))) == NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + /* This allocates the decl block to module mapping used for error reporting */ + if ((state->decl_to_mod = calloc(state->next_decl_id + num_mod_decls, + sizeof(*(state->decl_to_mod)))) == + NULL) { + ERR(state->handle, "Out of memory!"); + return -1; + } + cur = state->base->global; + while (cur != NULL) { + avrule_decl_t *decl = cur->branch_list; + while (decl != NULL) { + state->base->decl_val_to_struct[decl->decl_id - 1] = + decl; + state->decl_to_mod[decl->decl_id] = state->base; + decl = decl->next; + } + cur = cur->next; + } + + /* normalize conditionals within */ + if (cond_normalize(state->base) < 0) { + ERR(state->handle, + "Error while normalizing conditionals within the base module."); + return -1; + } + return 0; +} + +static int expand_role_attributes(hashtab_key_t key, hashtab_datum_t datum, + void * data) +{ + char *id; + role_datum_t *role, *sub_attr; + link_state_t *state; + unsigned int i; + ebitmap_node_t *rnode; + + id = key; + role = (role_datum_t *)datum; + state = (link_state_t *)data; + + if (strcmp(id, OBJECT_R) == 0){ + /* object_r is never a role attribute by far */ + return 0; + } + + if (role->flavor != ROLE_ATTRIB) + return 0; + + if (state->verbose) + INFO(state->handle, "expanding role attribute %s", id); + +restart: + ebitmap_for_each_positive_bit(&role->roles, rnode, i) { + sub_attr = state->base->role_val_to_struct[i]; + if (sub_attr->flavor != ROLE_ATTRIB) + continue; + + /* remove the sub role attribute from the parent + * role attribute's roles ebitmap */ + if (ksu_ebitmap_set_bit(&role->roles, i, 0)) + return -1; + + /* loop dependency of role attributes */ + if (sub_attr->s.value == role->s.value) + continue; + + /* now go on to expand a sub role attribute + * by escalating its roles ebitmap */ + if (ebitmap_union(&role->roles, &sub_attr->roles)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + /* sub_attr->roles may contain other role attributes, + * re-scan the parent role attribute's roles ebitmap */ + goto restart; + } + + return 0; +} + +/* For any role attribute in a declaration's local symtab[SYM_ROLES] table, + * copy its roles ebitmap into its duplicate's in the base->p_roles.table. + */ +static int populate_decl_roleattributes(hashtab_key_t key, + hashtab_datum_t datum, + void *data) +{ + char *id = key; + role_datum_t *decl_role, *base_role; + link_state_t *state = (link_state_t *)data; + + decl_role = (role_datum_t *)datum; + + if (strcmp(id, OBJECT_R) == 0) { + /* object_r is never a role attribute by far */ + return 0; + } + + if (decl_role->flavor != ROLE_ATTRIB) + return 0; + + base_role = (role_datum_t *)hashtab_search(state->base->p_roles.table, + id); + assert(base_role != NULL && base_role->flavor == ROLE_ATTRIB); + + if (ebitmap_union(&base_role->roles, &decl_role->roles)) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + return 0; +} + +static int populate_roleattributes(link_state_t *state, policydb_t *pol) +{ + avrule_block_t *block; + avrule_decl_t *decl; + + if (state->verbose) + INFO(state->handle, "Populating role-attribute relationship " + "from enabled declarations' local symtab."); + + /* Iterate through all of the blocks skipping the first(which is the + * global block, is required to be present and can't have an else). + * If the block is disabled or not having an enabled decl, skip it. + */ + for (block = pol->global->next; block != NULL; block = block->next) + { + decl = block->enabled; + if (decl == NULL || decl->enabled == 0) + continue; + + if (ksu_hashtab_map(decl->symtab[SYM_ROLES].table, + populate_decl_roleattributes, state)) + return -1; + } + + return 0; +} + +/* Link a set of modules into a base module. This process is somewhat + * similar to an actual compiler: it requires a set of order dependent + * steps. The base and every module must have been indexed prior to + * calling this function. + */ +int link_modules(sepol_handle_t * handle, + policydb_t * b, policydb_t ** mods, int len, int verbose) +{ + int i, ret, retval = -1; + policy_module_t **modules = NULL; + link_state_t state; + uint32_t num_mod_decls = 0; + + memset(&state, 0, sizeof(state)); + state.base = b; + state.verbose = verbose; + state.handle = handle; + + if (b->policy_type != POLICY_BASE) { + ERR(state.handle, "Target of link was not a base policy."); + return -1; + } + + /* first allocate some space to hold the maps from module + * symbol's value to the destination symbol value; then do + * other preparation work */ + if ((modules = + (policy_module_t **) calloc(len, sizeof(*modules))) == NULL) { + ERR(state.handle, "Out of memory!"); + return -1; + } + for (i = 0; i < len; i++) { + if (mods[i]->policy_type != POLICY_MOD) { + ERR(state.handle, + "Tried to link in a policy that was not a module."); + goto cleanup; + } + + if (mods[i]->mls != b->mls) { + if (b->mls) + ERR(state.handle, + "Tried to link in a non-MLS module with an MLS base."); + else + ERR(state.handle, + "Tried to link in an MLS module with a non-MLS base."); + goto cleanup; + } + + if (mods[i]->policyvers > b->policyvers) { + WARN(state.handle, + "Upgrading policy version from %u to %u", b->policyvers, mods[i]->policyvers); + b->policyvers = mods[i]->policyvers; + } + + if ((modules[i] = + (policy_module_t *) calloc(1, + sizeof(policy_module_t))) == + NULL) { + ERR(state.handle, "Out of memory!"); + goto cleanup; + } + modules[i]->policy = mods[i]; + if (prepare_module(&state, modules[i]) == -1) { + goto cleanup; + } + num_mod_decls += modules[i]->num_decls; + } + if (prepare_base(&state, num_mod_decls) == -1) { + goto cleanup; + } + + /* copy and remap the module's data over to base */ + for (i = 0; i < len; i++) { + state.cur = modules[i]; + ret = copy_module(&state, modules[i]); + if (ret) { + retval = ret; + goto cleanup; + } + } + + /* re-index base, for symbols were added to symbol tables */ + if (policydb_index_classes(state.base)) { + ERR(state.handle, "Error while indexing classes"); + goto cleanup; + } + if (policydb_index_others(state.handle, state.base, 0)) { + ERR(state.handle, "Error while indexing others"); + goto cleanup; + } + + if (enable_avrules(&state, state.base)) { + retval = SEPOL_EREQ; + goto cleanup; + } + + /* Now that all role attribute's roles ebitmap have been settled, + * escalate sub role attribute's roles ebitmap into that of parent. + * + * First, since some role-attribute relationships could be recorded + * in some decl's local symtab(see get_local_role()), we need to + * populate them up to the base.p_roles table. */ + if (populate_roleattributes(&state, state.base)) { + retval = SEPOL_EREQ; + goto cleanup; + } + + /* Now do the escalation. */ + if (ksu_hashtab_map(state.base->p_roles.table, expand_role_attributes, + &state)) + goto cleanup; + + retval = 0; + cleanup: + for (i = 0; modules != NULL && i < len; i++) { + policy_module_destroy(modules[i]); + } + free(modules); + free(state.decl_to_mod); + return retval; +} diff --git a/kernel/libsepol/src/link.o b/kernel/libsepol/src/link.o new file mode 100644 index 00000000..61e9e95e Binary files /dev/null and b/kernel/libsepol/src/link.o differ diff --git a/kernel/libsepol/src/mls.c b/kernel/libsepol/src/mls.c new file mode 100644 index 00000000..80537e2d --- /dev/null +++ b/kernel/libsepol/src/mls.c @@ -0,0 +1,815 @@ +/* Author : Stephen Smalley, */ +/* + * Updated: Trusted Computer Solutions, Inc. + * + * Support for enhanced MLS infrastructure. + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * Implementation of the multi-level security (MLS) policy. + */ + +#include +#include +#include +#include + +// #include + +#include "handle.h" +#include "debug.h" +#include "private.h" +#include "mls.h" + +int mls_to_string(sepol_handle_t * handle, + const policydb_t * policydb, + const context_struct_t * mls, char **str) +{ + + char *ptr = NULL, *ptr2 = NULL; + + /* Temporary buffer - length + NULL terminator */ + int len = ksu_mls_compute_context_len(policydb, mls) + 1; + + ptr = (char *)malloc(len); + if (ptr == NULL) + goto omem; + + /* Final string w/ ':' cut off */ + ptr2 = (char *)malloc(len - 1); + if (ptr2 == NULL) + goto omem; + + ksu_mls_sid_to_context(policydb, mls, &ptr); + ptr -= len - 1; + strcpy(ptr2, ptr + 1); + + free(ptr); + *str = ptr2; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory, could not convert mls context to string"); + + free(ptr); + free(ptr2); + return STATUS_ERR; + +} + +int ksu_mls_from_string(sepol_handle_t * handle, + const policydb_t * policydb, + const char *str, context_struct_t * mls) +{ + + char *tmp = strdup(str); + char *tmp_cp = tmp; + if (!tmp) + goto omem; + + if (ksu_mls_context_to_sid(policydb, '$', &tmp_cp, mls) < 0) { + ERR(handle, "invalid MLS context %s", str); + free(tmp); + goto err; + } + + free(tmp); + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + ERR(handle, "could not construct mls context structure"); + return STATUS_ERR; +} + +/* + * Return the length in bytes for the MLS fields of the + * security context string representation of `context'. + */ +int ksu_mls_compute_context_len(const policydb_t * policydb, + const context_struct_t * context) +{ + + unsigned int i, l, len, range; + ebitmap_node_t *cnode; + + if (!policydb->mls) + return 0; + + len = 1; /* for the beginning ":" */ + for (l = 0; l < 2; l++) { + range = 0; + len += + strlen(policydb-> + p_sens_val_to_name[context->range.level[l].sens - + 1]); + + ebitmap_for_each_bit(&context->range.level[l].cat, cnode, i) { + if (ebitmap_node_get_bit(cnode, i)) { + if (range) { + range++; + continue; + } + + len += + strlen(policydb->p_cat_val_to_name[i]) + 1; + range++; + } else { + if (range > 1) + len += + strlen(policydb-> + p_cat_val_to_name[i - 1]) + + 1; + range = 0; + } + } + /* Handle case where last category is the end of range */ + if (range > 1) + len += strlen(policydb->p_cat_val_to_name[i - 1]) + 1; + + if (l == 0) { + if (mls_level_eq(&context->range.level[0], + &context->range.level[1])) + break; + else + len++; + } + } + + return len; +} + +/* + * Write the security context string representation of + * the MLS fields of `context' into the string `*scontext'. + * Update `*scontext' to point to the end of the MLS fields. + */ +void ksu_mls_sid_to_context(const policydb_t * policydb, + const context_struct_t * context, char **scontext) +{ + + char *scontextp; + unsigned int i, l, range, wrote_sep; + ebitmap_node_t *cnode; + + if (!policydb->mls) + return; + + scontextp = *scontext; + + *scontextp = ':'; + scontextp++; + + for (l = 0; l < 2; l++) { + range = 0; + wrote_sep = 0; + strcpy(scontextp, + policydb->p_sens_val_to_name[context->range.level[l]. + sens - 1]); + scontextp += + strlen(policydb-> + p_sens_val_to_name[context->range.level[l].sens - + 1]); + /* categories */ + ebitmap_for_each_bit(&context->range.level[l].cat, cnode, i) { + if (ebitmap_node_get_bit(cnode, i)) { + if (range) { + range++; + continue; + } + + if (!wrote_sep) { + *scontextp++ = ':'; + wrote_sep = 1; + } else + *scontextp++ = ','; + strcpy(scontextp, + policydb->p_cat_val_to_name[i]); + scontextp += + strlen(policydb->p_cat_val_to_name[i]); + range++; + } else { + if (range > 1) { + if (range > 2) + *scontextp++ = '.'; + else + *scontextp++ = ','; + + strcpy(scontextp, + policydb->p_cat_val_to_name[i - + 1]); + scontextp += + strlen(policydb-> + p_cat_val_to_name[i - 1]); + } + range = 0; + } + } + /* Handle case where last category is the end of range */ + if (range > 1) { + if (range > 2) + *scontextp++ = '.'; + else + *scontextp++ = ','; + + strcpy(scontextp, policydb->p_cat_val_to_name[i - 1]); + scontextp += strlen(policydb->p_cat_val_to_name[i - 1]); + } + + if (l == 0) { + if (mls_level_eq(&context->range.level[0], + &context->range.level[1])) + break; + else { + *scontextp = '-'; + scontextp++; + } + } + } + + *scontext = scontextp; + return; +} + +/* + * Return 1 if the MLS fields in the security context + * structure `c' are valid. Return 0 otherwise. + */ +int ksu_mls_context_isvalid(const policydb_t * p, const context_struct_t * c) +{ + + level_datum_t *levdatum; + user_datum_t *usrdatum; + unsigned int i, l; + ebitmap_node_t *cnode; + hashtab_key_t key; + + if (!p->mls) + return 1; + + /* + * MLS range validity checks: high must dominate low, low level must + * be valid (category set <-> sensitivity check), and high level must + * be valid (category set <-> sensitivity check) + */ + if (!mls_level_dom(&c->range.level[1], &c->range.level[0])) + /* High does not dominate low. */ + return 0; + + for (l = 0; l < 2; l++) { + if (!c->range.level[l].sens + || c->range.level[l].sens > p->p_levels.nprim) + return 0; + + key = p->p_sens_val_to_name[c->range.level[l].sens - 1]; + if (!key) + return 0; + + levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, key); + if (!levdatum) + return 0; + + ebitmap_for_each_positive_bit(&c->range.level[l].cat, cnode, i) { + if (i > p->p_cats.nprim) + return 0; + if (!ksu_ebitmap_get_bit(&levdatum->level->cat, i)) + /* + * Category may not be associated with + * sensitivity in low level. + */ + return 0; + } + } + + if (c->role == OBJECT_R_VAL) + return 1; + + /* + * User must be authorized for the MLS range. + */ + if (!c->user || c->user > p->p_users.nprim) + return 0; + usrdatum = p->user_val_to_struct[c->user - 1]; + if (!usrdatum || !mls_range_contains(usrdatum->exp_range, c->range)) + return 0; /* user may not be associated with range */ + + return 1; +} + +/* + * Set the MLS fields in the security context structure + * `context' based on the string representation in + * the string `*scontext'. Update `*scontext' to + * point to the end of the string representation of + * the MLS fields. + * + * This function modifies the string in place, inserting + * NULL characters to terminate the MLS fields. + */ +int ksu_mls_context_to_sid(const policydb_t * policydb, + char oldc, char **scontext, context_struct_t * context) +{ + + char delim; + char *scontextp, *p, *rngptr; + level_datum_t *levdatum; + cat_datum_t *catdatum, *rngdatum; + unsigned int l; + + if (!policydb->mls) + return 0; + + /* No MLS component to the security context */ + if (!oldc) + goto err; + + /* Extract low sensitivity. */ + scontextp = p = *scontext; + while (*p && *p != ':' && *p != '-') + p++; + + delim = *p; + if (delim != 0) + *p++ = 0; + + for (l = 0; l < 2; l++) { + levdatum = + (level_datum_t *) hashtab_search(policydb->p_levels.table, + (hashtab_key_t) scontextp); + + if (!levdatum) + goto err; + + context->range.level[l].sens = levdatum->level->sens; + + if (delim == ':') { + /* Extract category set. */ + while (1) { + scontextp = p; + while (*p && *p != ',' && *p != '-') + p++; + delim = *p; + if (delim != 0) + *p++ = 0; + + /* Separate into range if exists */ + if ((rngptr = strchr(scontextp, '.')) != NULL) { + /* Remove '.' */ + *rngptr++ = 0; + } + + catdatum = + (cat_datum_t *) hashtab_search(policydb-> + p_cats.table, + (hashtab_key_t) + scontextp); + if (!catdatum) + goto err; + + if (ksu_ebitmap_set_bit + (&context->range.level[l].cat, + catdatum->s.value - 1, 1)) + goto err; + + /* If range, set all categories in range */ + if (rngptr) { + unsigned int i; + + rngdatum = (cat_datum_t *) + hashtab_search(policydb->p_cats. + table, + (hashtab_key_t) + rngptr); + if (!rngdatum) + goto err; + + if (catdatum->s.value >= + rngdatum->s.value) + goto err; + + for (i = catdatum->s.value; + i < rngdatum->s.value; i++) { + if (ksu_ebitmap_set_bit + (&context->range.level[l]. + cat, i, 1)) + goto err; + } + } + + if (delim != ',') + break; + } + } + if (delim == '-') { + /* Extract high sensitivity. */ + scontextp = p; + while (*p && *p != ':') + p++; + + delim = *p; + if (delim != 0) + *p++ = 0; + } else + break; + } + + /* High level is missing, copy low level */ + if (l == 0) { + if (mls_level_cpy(&context->range.level[1], + &context->range.level[0]) < 0) + goto err; + } + *scontext = ++p; + + return STATUS_SUCCESS; + + err: + return STATUS_ERR; +} + +/* + * Copies the MLS range from `src' into `dst'. + */ +static inline int mls_copy_context(context_struct_t * dst, + const context_struct_t * src) +{ + int l, rc = 0; + + /* Copy the MLS range from the source context */ + for (l = 0; l < 2; l++) { + dst->range.level[l].sens = src->range.level[l].sens; + rc = ksu_ebitmap_cpy(&dst->range.level[l].cat, + &src->range.level[l].cat); + if (rc) + break; + } + + return rc; +} + +/* + * Copies the effective MLS range from `src' into `dst'. + */ +static inline int mls_scopy_context(context_struct_t * dst, + const context_struct_t * src) +{ + int l, rc = 0; + + /* Copy the MLS range from the source context */ + for (l = 0; l < 2; l++) { + dst->range.level[l].sens = src->range.level[0].sens; + rc = ksu_ebitmap_cpy(&dst->range.level[l].cat, + &src->range.level[0].cat); + if (rc) + break; + } + + return rc; +} + +/* + * Copies the MLS range `range' into `context'. + */ +static inline int mls_range_set(context_struct_t * context, const mls_range_t * range) +{ + int l, rc = 0; + + /* Copy the MLS range into the context */ + for (l = 0; l < 2; l++) { + context->range.level[l].sens = range->level[l].sens; + rc = ksu_ebitmap_cpy(&context->range.level[l].cat, + &range->level[l].cat); + if (rc) + break; + } + + return rc; +} + +int ksu_mls_setup_user_range(context_struct_t * fromcon, user_datum_t * user, + context_struct_t * usercon, int mls) +{ + if (mls) { + mls_level_t *fromcon_sen = &(fromcon->range.level[0]); + mls_level_t *fromcon_clr = &(fromcon->range.level[1]); + mls_level_t *user_low = &(user->exp_range.level[0]); + mls_level_t *user_clr = &(user->exp_range.level[1]); + mls_level_t *user_def = &(user->exp_dfltlevel); + mls_level_t *usercon_sen = &(usercon->range.level[0]); + mls_level_t *usercon_clr = &(usercon->range.level[1]); + + /* Honor the user's default level if we can */ + if (mls_level_between(user_def, fromcon_sen, fromcon_clr)) { + *usercon_sen = *user_def; + } else if (mls_level_between(fromcon_sen, user_def, user_clr)) { + *usercon_sen = *fromcon_sen; + } else if (mls_level_between(fromcon_clr, user_low, user_def)) { + *usercon_sen = *user_low; + } else + return -EINVAL; + + /* Lower the clearance of available contexts + if the clearance of "fromcon" is lower than + that of the user's default clearance (but + only if the "fromcon" clearance dominates + the user's computed sensitivity level) */ + if (mls_level_dom(user_clr, fromcon_clr)) { + *usercon_clr = *fromcon_clr; + } else if (mls_level_dom(fromcon_clr, user_clr)) { + *usercon_clr = *user_clr; + } else + return -EINVAL; + } + + return 0; +} + +/* + * Convert the MLS fields in the security context + * structure `c' from the values specified in the + * policy `oldp' to the values specified in the policy `newp'. + */ +int ksu_mls_convert_context(policydb_t * oldp, + policydb_t * newp, context_struct_t * c) +{ + level_datum_t *levdatum; + cat_datum_t *catdatum; + ebitmap_t bitmap; + unsigned int l, i; + ebitmap_node_t *cnode; + + if (!oldp->mls) + return 0; + + for (l = 0; l < 2; l++) { + levdatum = + (level_datum_t *) hashtab_search(newp->p_levels.table, + oldp-> + p_sens_val_to_name[c-> + range. + level + [l]. + sens - + 1]); + + if (!levdatum) + return -EINVAL; + c->range.level[l].sens = levdatum->level->sens; + + ebitmap_init(&bitmap); + ebitmap_for_each_positive_bit(&c->range.level[l].cat, cnode, i) { + int rc; + + catdatum = + (cat_datum_t *) hashtab_search(newp->p_cats. + table, + oldp-> + p_cat_val_to_name + [i]); + if (!catdatum) + return -EINVAL; + rc = ksu_ebitmap_set_bit(&bitmap, + catdatum->s.value - 1, 1); + if (rc) + return rc; + } + ksu_ebitmap_destroy(&c->range.level[l].cat); + c->range.level[l].cat = bitmap; + } + + return 0; +} + +int ksu_mls_compute_sid(policydb_t * policydb, + const context_struct_t * scontext, + const context_struct_t * tcontext, + sepol_security_class_t tclass, + uint32_t specified, context_struct_t * newcontext) +{ + range_trans_t rtr; + struct mls_range *r; + struct class_datum *cladatum; + int default_range = 0; + + if (!policydb->mls) + return 0; + + switch (specified) { + case AVTAB_TRANSITION: + /* Look for a range transition rule. */ + rtr.source_type = scontext->type; + rtr.target_type = tcontext->type; + rtr.target_class = tclass; + r = hashtab_search(policydb->range_tr, (hashtab_key_t) &rtr); + if (r) + return mls_range_set(newcontext, r); + + if (tclass && tclass <= policydb->p_classes.nprim) { + cladatum = policydb->class_val_to_struct[tclass - 1]; + if (cladatum) + default_range = cladatum->default_range; + } + + switch (default_range) { + case DEFAULT_SOURCE_LOW: + return mls_context_cpy_low(newcontext, scontext); + case DEFAULT_SOURCE_HIGH: + return mls_context_cpy_high(newcontext, scontext); + case DEFAULT_SOURCE_LOW_HIGH: + return mls_context_cpy(newcontext, scontext); + case DEFAULT_TARGET_LOW: + return mls_context_cpy_low(newcontext, tcontext); + case DEFAULT_TARGET_HIGH: + return mls_context_cpy_high(newcontext, tcontext); + case DEFAULT_TARGET_LOW_HIGH: + return mls_context_cpy(newcontext, tcontext); + case DEFAULT_GLBLUB: + return mls_context_glblub(newcontext, scontext, tcontext); + } + + /* Fallthrough */ + case AVTAB_CHANGE: + if (tclass == policydb->process_class) + /* Use the process MLS attributes. */ + return mls_copy_context(newcontext, scontext); + else + /* Use the process effective MLS attributes. */ + return mls_scopy_context(newcontext, scontext); + case AVTAB_MEMBER: + /* Use the process effective MLS attributes. */ + return mls_context_cpy_low(newcontext, scontext); + default: + return -EINVAL; + } + return -EINVAL; +} + +int sepol_mls_contains(sepol_handle_t * handle, + const sepol_policydb_t * policydb, + const char *mls1, const char *mls2, int *response) +{ + + context_struct_t *ctx1 = NULL, *ctx2 = NULL; + ctx1 = malloc(sizeof(context_struct_t)); + ctx2 = malloc(sizeof(context_struct_t)); + if (ctx1 == NULL || ctx2 == NULL) + goto omem; + context_init(ctx1); + context_init(ctx2); + + if (ksu_mls_from_string(handle, &policydb->p, mls1, ctx1) < 0) + goto err; + + if (ksu_mls_from_string(handle, &policydb->p, mls2, ctx2) < 0) + goto err; + + *response = mls_range_contains(ctx1->range, ctx2->range); + context_destroy(ctx1); + context_destroy(ctx2); + free(ctx1); + free(ctx2); + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + ERR(handle, "could not check if mls context %s contains %s", + mls1, mls2); + context_destroy(ctx1); + context_destroy(ctx2); + free(ctx1); + free(ctx2); + return STATUS_ERR; +} + +int sepol_mls_check(sepol_handle_t * handle, + const sepol_policydb_t * policydb, const char *mls) +{ + + int ret; + context_struct_t *con = malloc(sizeof(context_struct_t)); + if (!con) { + ERR(handle, "out of memory, could not check if " + "mls context %s is valid", mls); + return STATUS_ERR; + } + context_init(con); + + ret = ksu_mls_from_string(handle, &policydb->p, mls, con); + context_destroy(con); + free(con); + return ret; +} + +void mls_semantic_cat_init(mls_semantic_cat_t * c) +{ + memset(c, 0, sizeof(mls_semantic_cat_t)); +} + +void mls_semantic_cat_destroy(mls_semantic_cat_t * c __attribute__ ((unused))) +{ + /* it's currently a simple struct - really nothing to destroy */ + return; +} + +void mls_semantic_level_init(mls_semantic_level_t * l) +{ + memset(l, 0, sizeof(mls_semantic_level_t)); +} + +void mls_semantic_level_destroy(mls_semantic_level_t * l) +{ + mls_semantic_cat_t *cur, *next; + + if (l == NULL) + return; + + next = l->cat; + while (next) { + cur = next; + next = cur->next; + mls_semantic_cat_destroy(cur); + free(cur); + } +} + +int mls_semantic_level_cpy(mls_semantic_level_t * dst, + const mls_semantic_level_t * src) +{ + const mls_semantic_cat_t *cat; + mls_semantic_cat_t *newcat, *lnewcat = NULL; + + mls_semantic_level_init(dst); + dst->sens = src->sens; + cat = src->cat; + while (cat) { + newcat = + (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); + if (!newcat) + goto err; + + mls_semantic_cat_init(newcat); + if (lnewcat) + lnewcat->next = newcat; + else + dst->cat = newcat; + + newcat->low = cat->low; + newcat->high = cat->high; + + lnewcat = newcat; + cat = cat->next; + } + return 0; + + err: + mls_semantic_level_destroy(dst); + return -1; +} + +void mls_semantic_range_init(mls_semantic_range_t * r) +{ + mls_semantic_level_init(&r->level[0]); + mls_semantic_level_init(&r->level[1]); +} + +void mls_semantic_range_destroy(mls_semantic_range_t * r) +{ + mls_semantic_level_destroy(&r->level[0]); + mls_semantic_level_destroy(&r->level[1]); +} + +int mls_semantic_range_cpy(mls_semantic_range_t * dst, + const mls_semantic_range_t * src) +{ + if (mls_semantic_level_cpy(&dst->level[0], &src->level[0]) < 0) + return -1; + + if (mls_semantic_level_cpy(&dst->level[1], &src->level[1]) < 0) { + mls_semantic_level_destroy(&dst->level[0]); + return -1; + } + + return 0; +} diff --git a/kernel/libsepol/src/mls.h b/kernel/libsepol/src/mls.h new file mode 100644 index 00000000..e6684cdc --- /dev/null +++ b/kernel/libsepol/src/mls.h @@ -0,0 +1,67 @@ +/* Author: Stephen Smalley, + * Updated: Trusted Computer Solutions, Inc. + * + * Support for enhanced MLS infrastructure. + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _SEPOL_MLS_INTERNAL_H_ +#define _SEPOL_MLS_INTERNAL_H_ + +#include "policydb_internal.h" +#include +#include "handle.h" + +extern int ksu_mls_from_string(sepol_handle_t * handle, + const policydb_t * policydb, + const char *str, context_struct_t * mls); + +extern int mls_to_string(sepol_handle_t * handle, + const policydb_t * policydb, + const context_struct_t * mls, char **str); + +/* Deprecated */ +extern int ksu_mls_compute_context_len(const policydb_t * policydb, + const context_struct_t * context); + +/* Deprecated */ +extern void ksu_mls_sid_to_context(const policydb_t * policydb, + const context_struct_t * context, + char **scontext); + +/* Deprecated */ +extern int ksu_mls_context_to_sid(const policydb_t * policydb, + char oldc, + char **scontext, context_struct_t * context); + +extern int ksu_mls_context_isvalid(const policydb_t * p, + const context_struct_t * c); + +extern int ksu_mls_convert_context(policydb_t * oldp, + policydb_t * newp, context_struct_t * context); + +extern int ksu_mls_compute_sid(policydb_t * policydb, + const context_struct_t * scontext, + const context_struct_t * tcontext, + sepol_security_class_t tclass, + uint32_t specified, context_struct_t * newcontext); + +extern int ksu_mls_setup_user_range(context_struct_t * fromcon, user_datum_t * user, + context_struct_t * usercon, int mls); + +#endif diff --git a/kernel/libsepol/src/mls.o b/kernel/libsepol/src/mls.o new file mode 100644 index 00000000..39702249 Binary files /dev/null and b/kernel/libsepol/src/mls.o differ diff --git a/kernel/libsepol/src/module.c b/kernel/libsepol/src/module.c new file mode 100644 index 00000000..d6ed1deb --- /dev/null +++ b/kernel/libsepol/src/module.c @@ -0,0 +1,1010 @@ +/* Author: Karl MacMillan + * Jason Tang + * Chris PeBenito + * + * Copyright (C) 2004-2005 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "policydb_internal.h" +#include "module_internal.h" +#include +#include +#include +#include "debug.h" +#include "private.h" + +// #include +// #include +#include +// #include + +#define SEPOL_PACKAGE_SECTION_FC 0xf97cff90 +#define SEPOL_PACKAGE_SECTION_SEUSER 0x97cff91 +#define SEPOL_PACKAGE_SECTION_USER_EXTRA 0x97cff92 +#define SEPOL_PACKAGE_SECTION_NETFILTER 0x97cff93 + +static int policy_file_seek(struct policy_file *fp, size_t offset) +{ + switch (fp->type) { + case PF_USE_STDIO: +#if 0 + if (offset > LONG_MAX) { + errno = EFAULT; + return -1; + } + return fseek(fp->fp, (long)offset, SEEK_SET); +#else + return -1; +#endif + case PF_USE_MEMORY: + if (offset > fp->size) { + // errno = EFAULT; + return -1; + } + fp->data -= fp->size - fp->len; + fp->data += offset; + fp->len = fp->size - offset; + return 0; + default: + return 0; + } +} + +static int policy_file_length(struct policy_file *fp, size_t *out) +{ + // long prev_offset, end_offset; + // int rc; + switch (fp->type) { + case PF_USE_STDIO: +#if 0 + prev_offset = ftell(fp->fp); + if (prev_offset < 0) + return prev_offset; + rc = fseek(fp->fp, 0L, SEEK_END); + if (rc < 0) + return rc; + end_offset = ftell(fp->fp); + if (end_offset < 0) + return end_offset; + rc = fseek(fp->fp, prev_offset, SEEK_SET); + if (rc < 0) + return rc; + *out = end_offset; + break; +#else + return -1; +#endif + case PF_USE_MEMORY: + *out = fp->size; + break; + default: + *out = 0; + break; + } + return 0; +} + +static int module_package_init(sepol_module_package_t * p) +{ + memset(p, 0, sizeof(sepol_module_package_t)); + if (sepol_policydb_create(&p->policy)) + return -1; + + p->version = 1; + return 0; +} + +static int set_char(char **field, char *data, size_t len) +{ + if (*field) { + free(*field); + *field = NULL; + } + if (len) { + *field = malloc(len); + if (!*field) + return -1; + memcpy(*field, data, len); + } + return 0; +} + +int sepol_module_package_create(sepol_module_package_t ** p) +{ + int rc; + + *p = calloc(1, sizeof(sepol_module_package_t)); + if (!(*p)) + return -1; + + rc = module_package_init(*p); + if (rc < 0) { + free(*p); + *p = NULL; + } + + return rc; +} + + +/* Deallocates all memory associated with a module package, including + * the pointer itself. Does nothing if p is NULL. + */ +void sepol_module_package_free(sepol_module_package_t * p) +{ + if (p == NULL) + return; + + sepol_policydb_free(p->policy); + free(p->file_contexts); + free(p->seusers); + free(p->user_extra); + free(p->netfilter_contexts); + free(p); +} + + +char *sepol_module_package_get_file_contexts(sepol_module_package_t * p) +{ + return p->file_contexts; +} + +size_t sepol_module_package_get_file_contexts_len(sepol_module_package_t * p) +{ + return p->file_contexts_len; +} + +char *sepol_module_package_get_seusers(sepol_module_package_t * p) +{ + return p->seusers; +} + +size_t sepol_module_package_get_seusers_len(sepol_module_package_t * p) +{ + return p->seusers_len; +} + +char *sepol_module_package_get_user_extra(sepol_module_package_t * p) +{ + return p->user_extra; +} + +size_t sepol_module_package_get_user_extra_len(sepol_module_package_t * p) +{ + return p->user_extra_len; +} + +char *sepol_module_package_get_netfilter_contexts(sepol_module_package_t * p) +{ + return p->netfilter_contexts; +} + +size_t sepol_module_package_get_netfilter_contexts_len(sepol_module_package_t * + p) +{ + return p->netfilter_contexts_len; +} + +int sepol_module_package_set_file_contexts(sepol_module_package_t * p, + char *data, size_t len) +{ + if (set_char(&p->file_contexts, data, len)) + return -1; + + p->file_contexts_len = len; + return 0; +} + +int sepol_module_package_set_seusers(sepol_module_package_t * p, + char *data, size_t len) +{ + if (set_char(&p->seusers, data, len)) + return -1; + + p->seusers_len = len; + return 0; +} + +int sepol_module_package_set_user_extra(sepol_module_package_t * p, + char *data, size_t len) +{ + if (set_char(&p->user_extra, data, len)) + return -1; + + p->user_extra_len = len; + return 0; +} + +int sepol_module_package_set_netfilter_contexts(sepol_module_package_t * p, + char *data, size_t len) +{ + if (set_char(&p->netfilter_contexts, data, len)) + return -1; + + p->netfilter_contexts_len = len; + return 0; +} + +sepol_policydb_t *sepol_module_package_get_policy(sepol_module_package_t * p) +{ + return p->policy; +} + +/* Append each of the file contexts from each module to the base + * policy's file context. 'base_context' will be reallocated to a + * larger size (and thus it is an in/out reference + * variable). 'base_fc_len' is the length of base's file context; it + * too is a reference variable. Return 0 on success, -1 if out of + * memory. */ +static int link_file_contexts(sepol_module_package_t * base, + sepol_module_package_t ** modules, + int num_modules) +{ + size_t fc_len; + int i; + char *s; + + fc_len = base->file_contexts_len; + for (i = 0; i < num_modules; i++) { + fc_len += modules[i]->file_contexts_len; + } + + if ((s = (char *)realloc(base->file_contexts, fc_len)) == NULL) { + return -1; + } + base->file_contexts = s; + for (i = 0; i < num_modules; i++) { + memcpy(base->file_contexts + base->file_contexts_len, + modules[i]->file_contexts, + modules[i]->file_contexts_len); + base->file_contexts_len += modules[i]->file_contexts_len; + } + return 0; +} + +/* Append each of the netfilter contexts from each module to the base + * policy's netfilter context. 'base_context' will be reallocated to a + * larger size (and thus it is an in/out reference + * variable). 'base_nc_len' is the length of base's netfilter contexts; it + * too is a reference variable. Return 0 on success, -1 if out of + * memory. */ +static int link_netfilter_contexts(sepol_module_package_t * base, + sepol_module_package_t ** modules, + int num_modules) +{ + size_t base_nc_len; + int i; + char *base_context; + + base_nc_len = base->netfilter_contexts_len; + for (i = 0; i < num_modules; i++) { + base_nc_len += modules[i]->netfilter_contexts_len; + } + + if ((base_context = + (char *)realloc(base->netfilter_contexts, base_nc_len)) == NULL) { + return -1; + } + base->netfilter_contexts = base_context; + for (i = 0; i < num_modules; i++) { + if (modules[i]->netfilter_contexts_len > 0) { + memcpy(base->netfilter_contexts + base->netfilter_contexts_len, + modules[i]->netfilter_contexts, + modules[i]->netfilter_contexts_len); + base->netfilter_contexts_len += + modules[i]->netfilter_contexts_len; + } + + } + return 0; +} + +/* Links the module packages into the base. Returns 0 on success, -1 + * if a requirement was not met, or -2 for all other errors. */ +int sepol_link_packages(sepol_handle_t * handle, + sepol_module_package_t * base, + sepol_module_package_t ** modules, int num_modules, + int verbose) +{ + policydb_t **mod_pols = NULL; + int i, retval; + + if ((mod_pols = calloc(num_modules, sizeof(*mod_pols))) == NULL) { + ERR(handle, "Out of memory!"); + return -2; + } + for (i = 0; i < num_modules; i++) { + mod_pols[i] = &modules[i]->policy->p; + } + + retval = link_modules(handle, &base->policy->p, mod_pols, num_modules, + verbose); + free(mod_pols); + if (retval == -3) { + return -1; + } else if (retval < 0) { + return -2; + } + + if (link_file_contexts(base, modules, num_modules) == -1) { + ERR(handle, "Out of memory!"); + return -2; + } + + if (link_netfilter_contexts(base, modules, num_modules) == -1) { + ERR(handle, "Out of memory!"); + return -2; + } + + return 0; +} + +// http://aospxref.com/android-8.1.0_r81/xref/bionic/libc/include/stdio.h?fi=BUFSIZ#100 +#define BUFSIZ 1024 +/* buf must be large enough - no checks are performed */ +#define _read_helper_bufsize BUFSIZ +static int read_helper(char *buf, struct policy_file *file, uint32_t bytes) +{ + uint32_t offset, nel, read_len; + int rc; + + offset = 0; + nel = bytes; + + while (nel) { + if (nel < _read_helper_bufsize) + read_len = nel; + else + read_len = _read_helper_bufsize; + rc = next_entry(&buf[offset], file, read_len); + if (rc < 0) + return -1; + offset += read_len; + nel -= read_len; + } + return 0; +} + +#define MAXSECTIONS 100 + +/* Get the section offsets from a package file, offsets will be malloc'd to + * the appropriate size and the caller must free() them */ +static int module_package_read_offsets(sepol_module_package_t * mod, + struct policy_file *file, + size_t ** offsets, uint32_t * sections) +{ + uint32_t *buf = NULL, nsec; + unsigned i; + size_t *off = NULL; + int rc; + + buf = malloc(sizeof(uint32_t)*3); + if (!buf) { + ERR(file->handle, "out of memory"); + goto err; + } + + rc = next_entry(buf, file, sizeof(uint32_t) * 3); + if (rc < 0) { + ERR(file->handle, "module package header truncated"); + goto err; + } + if (le32_to_cpu(buf[0]) != SEPOL_MODULE_PACKAGE_MAGIC) { + ERR(file->handle, + "wrong magic number for module package: expected %#08x, got %#08x", + SEPOL_MODULE_PACKAGE_MAGIC, le32_to_cpu(buf[0])); + goto err; + } + + mod->version = le32_to_cpu(buf[1]); + nsec = *sections = le32_to_cpu(buf[2]); + + if (nsec > MAXSECTIONS) { + ERR(file->handle, "too many sections (%u) in module package", + nsec); + goto err; + } + + off = (size_t *) calloc(nsec + 1, sizeof(size_t)); + if (!off) { + ERR(file->handle, "out of memory"); + goto err; + } + + free(buf); + buf = calloc(nsec, sizeof(uint32_t)); + if (!buf) { + ERR(file->handle, "out of memory"); + goto err; + } + rc = next_entry(buf, file, sizeof(uint32_t) * nsec); + if (rc < 0) { + ERR(file->handle, "module package offset array truncated"); + goto err; + } + + for (i = 0; i < nsec; i++) { + off[i] = le32_to_cpu(buf[i]); + if (i && off[i] < off[i - 1]) { + ERR(file->handle, "offsets are not increasing (at %u, " + "offset %zu -> %zu", i, off[i - 1], + off[i]); + goto err; + } + } + + rc = policy_file_length(file, &off[nsec]); + if (rc < 0) + goto err; + + if (nsec && off[nsec] < off[nsec-1]) { + ERR(file->handle, "offset greater than file size (at %u, " + "offset %zu -> %zu", nsec, off[nsec - 1], + off[nsec]); + goto err; + } + *offsets = off; + free(buf); + return 0; + +err: + free(buf); + free(off); + return -1; +} + +/* Flags for which sections have been seen during parsing of module package. */ +#define SEEN_MOD 1 +#define SEEN_FC 2 +#define SEEN_SEUSER 4 +#define SEEN_USER_EXTRA 8 +#define SEEN_NETFILTER 16 + +int sepol_module_package_read(sepol_module_package_t * mod, + struct sepol_policy_file *spf, int verbose) +{ + struct policy_file *file = &spf->pf; + uint32_t buf[1], nsec; + size_t *offsets, len; + int rc; + unsigned i, seen = 0; + + if (module_package_read_offsets(mod, file, &offsets, &nsec)) + return -1; + + /* we know the section offsets, seek to them and read in the data */ + + for (i = 0; i < nsec; i++) { + + if (policy_file_seek(file, offsets[i])) { + ERR(file->handle, "error seeking to offset %zu for " + "module package section %u", offsets[i], i); + goto cleanup; + } + + len = offsets[i + 1] - offsets[i]; + + if (len < sizeof(uint32_t)) { + ERR(file->handle, "module package section %u " + "has too small length %zu", i, len); + goto cleanup; + } + + /* read the magic number, so that we know which function to call */ + rc = next_entry(buf, file, sizeof(uint32_t)); + if (rc < 0) { + ERR(file->handle, + "module package section %u truncated, lacks magic number", + i); + goto cleanup; + } + + switch (le32_to_cpu(buf[0])) { + case SEPOL_PACKAGE_SECTION_FC: + if (seen & SEEN_FC) { + ERR(file->handle, + "found multiple file contexts sections in module package (at section %u)", + i); + goto cleanup; + } + + mod->file_contexts_len = len - sizeof(uint32_t); + mod->file_contexts = + (char *)malloc(mod->file_contexts_len); + if (!mod->file_contexts) { + ERR(file->handle, "out of memory"); + goto cleanup; + } + if (read_helper + (mod->file_contexts, file, + mod->file_contexts_len)) { + ERR(file->handle, + "invalid file contexts section at section %u", + i); + free(mod->file_contexts); + mod->file_contexts = NULL; + goto cleanup; + } + seen |= SEEN_FC; + break; + case SEPOL_PACKAGE_SECTION_SEUSER: + if (seen & SEEN_SEUSER) { + ERR(file->handle, + "found multiple seuser sections in module package (at section %u)", + i); + goto cleanup; + } + + mod->seusers_len = len - sizeof(uint32_t); + mod->seusers = (char *)malloc(mod->seusers_len); + if (!mod->seusers) { + ERR(file->handle, "out of memory"); + goto cleanup; + } + if (read_helper(mod->seusers, file, mod->seusers_len)) { + ERR(file->handle, + "invalid seuser section at section %u", i); + free(mod->seusers); + mod->seusers = NULL; + goto cleanup; + } + seen |= SEEN_SEUSER; + break; + case SEPOL_PACKAGE_SECTION_USER_EXTRA: + if (seen & SEEN_USER_EXTRA) { + ERR(file->handle, + "found multiple user_extra sections in module package (at section %u)", + i); + goto cleanup; + } + + mod->user_extra_len = len - sizeof(uint32_t); + mod->user_extra = (char *)malloc(mod->user_extra_len); + if (!mod->user_extra) { + ERR(file->handle, "out of memory"); + goto cleanup; + } + if (read_helper + (mod->user_extra, file, mod->user_extra_len)) { + ERR(file->handle, + "invalid user_extra section at section %u", + i); + free(mod->user_extra); + mod->user_extra = NULL; + goto cleanup; + } + seen |= SEEN_USER_EXTRA; + break; + case SEPOL_PACKAGE_SECTION_NETFILTER: + if (seen & SEEN_NETFILTER) { + ERR(file->handle, + "found multiple netfilter contexts sections in module package (at section %u)", + i); + goto cleanup; + } + + mod->netfilter_contexts_len = len - sizeof(uint32_t); + mod->netfilter_contexts = + (char *)malloc(mod->netfilter_contexts_len); + if (!mod->netfilter_contexts) { + ERR(file->handle, "out of memory"); + goto cleanup; + } + if (read_helper + (mod->netfilter_contexts, file, + mod->netfilter_contexts_len)) { + ERR(file->handle, + "invalid netfilter contexts section at section %u", + i); + free(mod->netfilter_contexts); + mod->netfilter_contexts = NULL; + goto cleanup; + } + seen |= SEEN_NETFILTER; + break; + case POLICYDB_MOD_MAGIC: + if (seen & SEEN_MOD) { + ERR(file->handle, + "found multiple module sections in module package (at section %u)", + i); + goto cleanup; + } + + /* seek back to where the magic number was */ + if (policy_file_seek(file, offsets[i])) + goto cleanup; + + rc = ksu_policydb_read(&mod->policy->p, file, verbose); + if (rc < 0) { + ERR(file->handle, + "invalid module in module package (at section %u)", + i); + goto cleanup; + } + seen |= SEEN_MOD; + break; + default: + /* unknown section, ignore */ + ERR(file->handle, + "unknown magic number at section %u, offset: %zx, number: %x ", + i, offsets[i], le32_to_cpu(buf[0])); + break; + } + } + + if ((seen & SEEN_MOD) == 0) { + ERR(file->handle, "missing module in module package"); + goto cleanup; + } + + free(offsets); + return 0; + + cleanup: + free(offsets); + return -1; +} + +int sepol_module_package_info(struct sepol_policy_file *spf, int *type, + char **name, char **version) +{ + struct policy_file *file = &spf->pf; + sepol_module_package_t *mod = NULL; + uint32_t buf[5], len, nsec; + size_t *offsets = NULL; + unsigned i, seen = 0; + char *id; + int rc; + + if (sepol_module_package_create(&mod)) + return -1; + + if (module_package_read_offsets(mod, file, &offsets, &nsec)) { + goto cleanup; + } + + for (i = 0; i < nsec; i++) { + + if (policy_file_seek(file, offsets[i])) { + ERR(file->handle, "error seeking to offset " + "%zu for module package section %u", offsets[i], i); + goto cleanup; + } + + len = offsets[i + 1] - offsets[i]; + + if (len < sizeof(uint32_t)) { + ERR(file->handle, + "module package section %u has too small length %u", + i, len); + goto cleanup; + } + + /* read the magic number, so that we know which function to call */ + rc = next_entry(buf, file, sizeof(uint32_t) * 2); + if (rc < 0) { + ERR(file->handle, + "module package section %u truncated, lacks magic number", + i); + goto cleanup; + } + + switch (le32_to_cpu(buf[0])) { + case SEPOL_PACKAGE_SECTION_FC: + /* skip file contexts */ + if (seen & SEEN_FC) { + ERR(file->handle, + "found multiple file contexts sections in module package (at section %u)", + i); + goto cleanup; + } + seen |= SEEN_FC; + break; + case SEPOL_PACKAGE_SECTION_SEUSER: + /* skip seuser */ + if (seen & SEEN_SEUSER) { + ERR(file->handle, + "found seuser sections in module package (at section %u)", + i); + goto cleanup; + } + seen |= SEEN_SEUSER; + break; + case SEPOL_PACKAGE_SECTION_USER_EXTRA: + /* skip user_extra */ + if (seen & SEEN_USER_EXTRA) { + ERR(file->handle, + "found user_extra sections in module package (at section %u)", + i); + goto cleanup; + } + seen |= SEEN_USER_EXTRA; + break; + case SEPOL_PACKAGE_SECTION_NETFILTER: + /* skip netfilter contexts */ + if (seen & SEEN_NETFILTER) { + ERR(file->handle, + "found multiple netfilter contexts sections in module package (at section %u)", + i); + goto cleanup; + } + seen |= SEEN_NETFILTER; + break; + case POLICYDB_MOD_MAGIC: + if (seen & SEEN_MOD) { + ERR(file->handle, + "found multiple module sections in module package (at section %u)", + i); + goto cleanup; + } + len = le32_to_cpu(buf[1]); + if (len != strlen(POLICYDB_MOD_STRING)) { + ERR(file->handle, + "module string length is wrong (at section %u)", + i); + goto cleanup; + } + + /* skip id */ + id = malloc(len + 1); + if (!id) { + ERR(file->handle, + "out of memory (at section %u)", + i); + goto cleanup; + } + rc = next_entry(id, file, len); + free(id); + if (rc < 0) { + ERR(file->handle, + "cannot get module string (at section %u)", + i); + goto cleanup; + } + + rc = next_entry(buf, file, sizeof(uint32_t) * 5); + if (rc < 0) { + ERR(file->handle, + "cannot get module header (at section %u)", + i); + goto cleanup; + } + + *type = le32_to_cpu(buf[0]); + /* if base - we're done */ + if (*type == POLICY_BASE) { + *name = NULL; + *version = NULL; + seen |= SEEN_MOD; + break; + } else if (*type != POLICY_MOD) { + ERR(file->handle, + "module has invalid type %d (at section %u)", + *type, i); + goto cleanup; + } + + /* read the name and version */ + rc = next_entry(buf, file, sizeof(uint32_t)); + if (rc < 0) { + ERR(file->handle, + "cannot get module name len (at section %u)", + i); + goto cleanup; + } + + len = le32_to_cpu(buf[0]); + if (str_read(name, file, len)) { + ERR(file->handle, + "cannot read module name (at section %u): %m", + i); + goto cleanup; + } + + rc = next_entry(buf, file, sizeof(uint32_t)); + if (rc < 0) { + ERR(file->handle, + "cannot get module version len (at section %u)", + i); + goto cleanup; + } + len = le32_to_cpu(buf[0]); + if (str_read(version, file, len)) { + ERR(file->handle, + "cannot read module version (at section %u): %m", + i); + goto cleanup; + } + seen |= SEEN_MOD; + break; + default: + break; + } + + } + + if ((seen & SEEN_MOD) == 0) { + ERR(file->handle, "missing module in module package"); + goto cleanup; + } + + sepol_module_package_free(mod); + free(offsets); + return 0; + + cleanup: + sepol_module_package_free(mod); + free(offsets); + return -1; +} + +static int write_helper(char *data, size_t len, struct policy_file *file) +{ + int idx = 0; + size_t len2; + + while (len) { + if (len > BUFSIZ) + len2 = BUFSIZ; + else + len2 = len; + + if (put_entry(&data[idx], 1, len2, file) != len2) { + return -1; + } + len -= len2; + idx += len2; + } + return 0; +} + +int sepol_module_package_write(sepol_module_package_t * p, + struct sepol_policy_file *spf) +{ + struct policy_file *file = &spf->pf; + policy_file_t polfile; + uint32_t buf[5], offsets[5], len, nsec = 0; + int i; + + if (p->policy) { + /* compute policy length */ + policy_file_init(&polfile); + polfile.type = PF_LEN; + polfile.handle = file->handle; + if (ksu_policydb_write(&p->policy->p, &polfile)) + return -1; + len = polfile.len; + if (!polfile.len) + return -1; + nsec++; + + } else { + /* We don't support writing a package without a module at this point */ + return -1; + } + + /* seusers and user_extra only supported in base at the moment */ + if ((p->seusers || p->user_extra) + && (p->policy->p.policy_type != SEPOL_POLICY_BASE)) { + ERR(file->handle, + "seuser and user_extra sections only supported in base"); + return -1; + } + + if (p->file_contexts) + nsec++; + + if (p->seusers) + nsec++; + + if (p->user_extra) + nsec++; + + if (p->netfilter_contexts) + nsec++; + + buf[0] = cpu_to_le32(SEPOL_MODULE_PACKAGE_MAGIC); + buf[1] = cpu_to_le32(p->version); + buf[2] = cpu_to_le32(nsec); + if (put_entry(buf, sizeof(uint32_t), 3, file) != 3) + return -1; + + /* calculate offsets */ + offsets[0] = (nsec + 3) * sizeof(uint32_t); + buf[0] = cpu_to_le32(offsets[0]); + + i = 1; + if (p->file_contexts) { + offsets[i] = offsets[i - 1] + len; + buf[i] = cpu_to_le32(offsets[i]); + /* add a uint32_t to compensate for the magic number */ + len = p->file_contexts_len + sizeof(uint32_t); + i++; + } + if (p->seusers) { + offsets[i] = offsets[i - 1] + len; + buf[i] = cpu_to_le32(offsets[i]); + len = p->seusers_len + sizeof(uint32_t); + i++; + } + if (p->user_extra) { + offsets[i] = offsets[i - 1] + len; + buf[i] = cpu_to_le32(offsets[i]); + len = p->user_extra_len + sizeof(uint32_t); + i++; + } + if (p->netfilter_contexts) { + offsets[i] = offsets[i - 1] + len; + buf[i] = cpu_to_le32(offsets[i]); + len = p->netfilter_contexts_len + sizeof(uint32_t); + i++; + } + if (put_entry(buf, sizeof(uint32_t), nsec, file) != nsec) + return -1; + + /* write sections */ + + if (ksu_policydb_write(&p->policy->p, file)) + return -1; + + if (p->file_contexts) { + buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_FC); + if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) + return -1; + if (write_helper(p->file_contexts, p->file_contexts_len, file)) + return -1; + } + if (p->seusers) { + buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_SEUSER); + if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) + return -1; + if (write_helper(p->seusers, p->seusers_len, file)) + return -1; + + } + if (p->user_extra) { + buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_USER_EXTRA); + if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) + return -1; + if (write_helper(p->user_extra, p->user_extra_len, file)) + return -1; + } + if (p->netfilter_contexts) { + buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_NETFILTER); + if (put_entry(buf, sizeof(uint32_t), 1, file) != 1) + return -1; + if (write_helper + (p->netfilter_contexts, p->netfilter_contexts_len, file)) + return -1; + } + return 0; +} + +int sepol_link_modules(sepol_handle_t * handle, + sepol_policydb_t * base, + sepol_policydb_t ** modules, size_t len, int verbose) +{ + return link_modules(handle, &base->p, (policydb_t **) modules, len, + verbose); +} + +int sepol_expand_module(sepol_handle_t * handle, + sepol_policydb_t * base, + sepol_policydb_t * out, int verbose, int check) +{ + return expand_module(handle, &base->p, &out->p, verbose, check); +} diff --git a/kernel/libsepol/src/module.o b/kernel/libsepol/src/module.o new file mode 100644 index 00000000..17cd5afe Binary files /dev/null and b/kernel/libsepol/src/module.o differ diff --git a/kernel/libsepol/src/module_internal.h b/kernel/libsepol/src/module_internal.h new file mode 100644 index 00000000..ac1be36a --- /dev/null +++ b/kernel/libsepol/src/module_internal.h @@ -0,0 +1,2 @@ +#include + diff --git a/kernel/libsepol/src/module_to_cil.c b/kernel/libsepol/src/module_to_cil.c new file mode 100644 index 00000000..36a7b0b4 --- /dev/null +++ b/kernel/libsepol/src/module_to_cil.c @@ -0,0 +1,4267 @@ +/* Authors: Steve Lawrence + * + * Functions to convert policy module to CIL + * + * Copyright (C) 2015 Tresys Technology, LLC + * Copyright (C) 2017 Mellanox Technologies Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// #include +#include +#include +// #include +// #include +// #include +// #include +// #include +#include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif +// #include +// #include +// #include +// #include +#include +// #include +#include +// #include +// #include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kernel_to_common.h" +#include "private.h" +#include "module_internal.h" + +#ifdef __GNUC__ +# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) +#else +# define UNUSED(x) UNUSED_ ## x +#endif + +static FILE *out_file; + +#define STACK_SIZE 16 +#define DEFAULT_LEVEL "systemlow" +#define DEFAULT_OBJECT "object_r" +#define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/cil/src/cil_post.c */ +#define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/cil/src/cil_post.c */ +#define ROLEATTR_INFIX "_roleattr_" + +__attribute__ ((format(printf, 1, 2))) +static void log_err(const char *fmt, ...) +{ + va_list argptr; + va_start(argptr, fmt); + if (vfprintf(stderr, fmt, argptr) < 0) { + _exit(EXIT_FAILURE); + } + va_end(argptr); + if (fprintf(stderr, "\n") < 0) { + _exit(EXIT_FAILURE); + } +} + +static void cil_indent(int indent) +{ + if (fprintf(out_file, "%*s", indent * 4, "") < 0) { + log_err("Failed to write to output"); + _exit(EXIT_FAILURE); + } +} + +__attribute__ ((format(printf, 1, 2))) +static void cil_printf(const char *fmt, ...) { + va_list argptr; + va_start(argptr, fmt); + if (vfprintf(out_file, fmt, argptr) < 0) { + log_err("Failed to write to output"); + _exit(EXIT_FAILURE); + } + va_end(argptr); +} + +__attribute__ ((format(printf, 2, 3))) +static void cil_println(int indent, const char *fmt, ...) +{ + va_list argptr; + cil_indent(indent); + va_start(argptr, fmt); + if (vfprintf(out_file, fmt, argptr) < 0) { + log_err("Failed to write to output"); + _exit(EXIT_FAILURE); + } + va_end(argptr); + if (fprintf(out_file, "\n") < 0) { + log_err("Failed to write to output"); + _exit(EXIT_FAILURE); + } +} + +static int get_line(char **start, char *end, char **line) +{ + int rc = 1; + char *p = NULL; + size_t len = 0; + + *line = NULL; + + for (p = *start; p < end && isspace(*p); p++); + + *start = p; + + for (len = 0; p < end && *p != '\n' && *p != '\0'; p++, len++); + + if (zero_or_saturated(len)) { + rc = 0; + goto exit; + } + + *line = malloc(len+1); + if (*line == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + + memcpy(*line, *start, len); + (*line)[len] = '\0'; + + *start = p; + + return rc; + +exit: + *start = NULL; + return rc; +} + +struct map_args { + struct policydb *pdb; + struct avrule_block *block; + struct stack *decl_stack; + int scope; + int indent; + int sym_index; +}; + +struct stack { + void **stack; + int pos; + int size; +}; + +struct role_list_node { + char *role_name; + role_datum_t *role; +}; + +struct attr_list_node { + char *attr_name; + int is_type; + void *set; +}; + +struct list_node { + void *data; + struct list_node *next; +}; + +struct list { + struct list_node *head; +}; + +/* A linked list of all roles stored in the pdb + * which is iterated to determine types associated + * with each role when printing role_type statements + */ +static struct list *role_list; + +static void list_destroy(struct list **list) +{ + struct list_node *curr = (*list)->head; + struct list_node *tmp; + + while (curr != NULL) { + tmp = curr->next; + free(curr); + curr = tmp; + } + + free(*list); + *list = NULL; +} + +static void role_list_destroy(void) +{ + struct list_node *curr; + + if (role_list == NULL) { + return; + } + curr = role_list->head; + + while (curr != NULL) { + free(curr->data); + curr->data = NULL; + curr = curr->next; + } + + list_destroy(&role_list); +} + +static void attr_list_destroy(struct list **attr_list) +{ + struct list_node *curr; + struct attr_list_node *attr; + + if (attr_list == NULL || *attr_list == NULL) { + return; + } + + curr = (*attr_list)->head; + + while (curr != NULL) { + attr = curr->data; + if (attr != NULL) { + free(attr->attr_name); + } + + free(curr->data); + curr->data = NULL; + curr = curr->next; + } + + list_destroy(attr_list); +} + +static int list_init(struct list **list) +{ + struct list *l = calloc(1, sizeof(*l)); + if (l == NULL) { + return -1; + } + + *list = l; + return 0; +} + +static int list_prepend(struct list *list, void *data) +{ + int rc = -1; + struct list_node *node = calloc(1, sizeof(*node)); + if (node == NULL) { + goto exit; + } + + node->data = data; + node->next = list->head; + list->head = node; + + rc = 0; + +exit: + return rc; +} + +static int roles_gather_map(char *key, void *data, void *args) +{ + struct role_list_node *role_node; + role_datum_t *role = data; + int rc = -1; + + role_node = calloc(1, sizeof(*role_node)); + if (role_node == NULL) { + return rc; + } + + role_node->role_name = key; + role_node->role = role; + + rc = list_prepend((struct list *)args, role_node); + if (rc != 0) + free(role_node); + return rc; +} + +static int role_list_create(hashtab_t roles_tab) +{ + int rc = -1; + + rc = list_init(&role_list); + if (rc != 0) { + goto exit; + } + + rc = ksu_hashtab_map(roles_tab, roles_gather_map, role_list); + +exit: + return rc; +} + +// array of lists, where each list contains all the aliases defined in the scope at index i +static struct list **typealias_lists; +static uint32_t typealias_lists_len; + +static int typealiases_gather_map(char *key, void *data, void *arg) +{ + int rc = -1; + struct type_datum *type = data; + struct policydb *pdb = arg; + struct scope_datum *scope; + uint32_t len; + uint32_t scope_id; + + if (type->primary != 1) { + scope = hashtab_search(pdb->scope[SYM_TYPES].table, key); + if (scope == NULL) { + return -1; + } + + len = scope->decl_ids_len; + if (len > 0) { + scope_id = scope->decl_ids[len-1]; + if (typealias_lists[scope_id] == NULL) { + rc = list_init(&typealias_lists[scope_id]); + if (rc != 0) { + goto exit; + } + } + /* As typealias_lists[scope_id] does not hold the + * ownership of its items (typealias_list_destroy does + * not free the list items), "key" does not need to be + * strdup'ed before it is inserted in the list. + */ + list_prepend(typealias_lists[scope_id], key); + } + } + + return 0; + +exit: + return rc; +} + +static void typealias_list_destroy(void) +{ + uint32_t i; + for (i = 0; i < typealias_lists_len; i++) { + if (typealias_lists[i] != NULL) { + list_destroy(&typealias_lists[i]); + } + } + typealias_lists_len = 0; + free(typealias_lists); + typealias_lists = NULL; +} + +static int typealias_list_create(struct policydb *pdb) +{ + uint32_t max_decl_id = 0; + struct avrule_decl *decl; + struct avrule_block *block; + uint32_t rc = -1; + + for (block = pdb->global; block != NULL; block = block->next) { + decl = block->branch_list; + if (decl != NULL && decl->decl_id > max_decl_id) { + max_decl_id = decl->decl_id; + } + } + + typealias_lists = calloc(max_decl_id + 1, sizeof(*typealias_lists)); + if (!typealias_lists) + goto exit; + typealias_lists_len = max_decl_id + 1; + + rc = ksu_hashtab_map(pdb->p_types.table, typealiases_gather_map, pdb); + if (rc != 0) { + goto exit; + } + + return 0; + +exit: + typealias_list_destroy(); + + return rc; +} + + +static int stack_destroy(struct stack **stack) +{ + if (stack == NULL || *stack == NULL) { + return 0; + } + + free((*stack)->stack); + free(*stack); + *stack = NULL; + + return 0; +} + +static int stack_init(struct stack **stack) +{ + int rc = -1; + struct stack *s = calloc(1, sizeof(*s)); + if (s == NULL) { + goto exit; + } + + s->stack = calloc(STACK_SIZE, sizeof(*s->stack)); + if (s->stack == NULL) { + goto exit; + } + + s->pos = -1; + s->size = STACK_SIZE; + + *stack = s; + + return 0; + +exit: + stack_destroy(&s); + return rc; +} + +static int stack_push(struct stack *stack, void *ptr) +{ + int rc = -1; + void *new_stack; + + if (stack->pos + 1 == stack->size) { + new_stack = reallocarray(stack->stack, stack->size * 2, sizeof(*stack->stack)); + if (new_stack == NULL) { + goto exit; + } + stack->stack = new_stack; + stack->size *= 2; + } + + stack->pos++; + stack->stack[stack->pos] = ptr; + + rc = 0; +exit: + return rc; +} + +static void *stack_pop(struct stack *stack) +{ + if (stack->pos == -1) { + return NULL; + } + + stack->pos--; + return stack->stack[stack->pos + 1]; +} + +static void *stack_peek(struct stack *stack) +{ + if (stack->pos == -1) { + return NULL; + } + + return stack->stack[stack->pos]; +} + +static int is_id_in_scope_with_start(struct policydb *pdb, struct stack *decl_stack, int start, uint32_t symbol_type, char *id) +{ + int i; + uint32_t j; + struct avrule_decl *decl; + struct scope_datum *scope; + + scope = hashtab_search(pdb->scope[symbol_type].table, id); + if (scope == NULL) { + return 0; + } + + for (i = start; i >= 0; i--) { + decl = decl_stack->stack[i]; + + for (j = 0; j < scope->decl_ids_len; j++) { + if (scope->decl_ids[j] == decl->decl_id) { + return 1; + } + } + } + + return 0; +} + +static int is_id_in_ancestor_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type) +{ + int start = decl_stack->pos - 1; + + return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type); +} + +static int is_id_in_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type) +{ + int start = decl_stack->pos; + + return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type); +} + +static int semantic_level_to_cil(struct policydb *pdb, int sens_offset, struct mls_semantic_level *level) +{ + struct mls_semantic_cat *cat; + + cil_printf("(%s ", pdb->p_sens_val_to_name[level->sens - sens_offset]); + + if (level->cat != NULL) { + cil_printf("("); + } + + for (cat = level->cat; cat != NULL; cat = cat->next) { + if (cat->low == cat->high) { + cil_printf("%s", pdb->p_cat_val_to_name[cat->low - 1]); + } else { + cil_printf("range %s %s", pdb->p_cat_val_to_name[cat->low - 1], pdb->p_cat_val_to_name[cat->high - 1]); + } + + if (cat->next != NULL) { + cil_printf(" "); + } + } + + if (level->cat != NULL) { + cil_printf(")"); + } + + cil_printf(")"); + + return 0; +} + +static int avrule_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const struct class_perm_node *classperms) +{ + int rc = -1; + const char *rule; + const struct class_perm_node *classperm; + char *perms; + + switch (type) { + case AVRULE_ALLOWED: + rule = "allow"; + break; + case AVRULE_AUDITALLOW: + rule = "auditallow"; + break; + case AVRULE_AUDITDENY: + rule = "auditdeny"; + break; + case AVRULE_DONTAUDIT: + rule = "dontaudit"; + break; + case AVRULE_NEVERALLOW: + rule = "neverallow"; + break; + case AVRULE_TRANSITION: + rule = "typetransition"; + break; + case AVRULE_MEMBER: + rule = "typemember"; + break; + case AVRULE_CHANGE: + rule = "typechange"; + break; + default: + log_err("Unknown avrule type: %i", type); + rc = -1; + goto exit; + } + + for (classperm = classperms; classperm != NULL; classperm = classperm->next) { + if (type & AVRULE_AV) { + perms = sepol_av_to_string(pdb, classperm->tclass, classperm->data); + if (perms == NULL) { + log_err("Failed to generate permission string"); + rc = -1; + goto exit; + } + cil_println(indent, "(%s %s %s (%s (%s)))", + rule, src, tgt, + pdb->p_class_val_to_name[classperm->tclass - 1], + perms + 1); + } else { + cil_println(indent, "(%s %s %s %s %s)", + rule, src, tgt, + pdb->p_class_val_to_name[classperm->tclass - 1], + pdb->p_type_val_to_name[classperm->data - 1]); + } + } + + return 0; + +exit: + return rc; +} + +#define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p)) + +static int xperms_to_cil(const av_extended_perms_t *xperms) +{ + uint16_t value; + uint16_t low_bit; + uint16_t low_value; + unsigned int bit; + unsigned int in_range = 0; + int first = 1; + + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) + return -1; + + for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { + if (!xperm_test(bit, xperms->perms)) + continue; + + if (in_range && next_bit_in_range(bit, xperms->perms)) { + /* continue until high value found */ + continue; + } else if (next_bit_in_range(bit, xperms->perms)) { + /* low value */ + low_bit = bit; + in_range = 1; + continue; + } + + if (!first) + cil_printf(" "); + else + first = 0; + + if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { + value = xperms->driver<<8 | bit; + if (in_range) { + low_value = xperms->driver<<8 | low_bit; + cil_printf("(range 0x%hx 0x%hx)", low_value, value); + in_range = 0; + } else { + cil_printf("0x%hx", value); + } + } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { + value = bit << 8; + if (in_range) { + low_value = low_bit << 8; + cil_printf("(range 0x%hx 0x%hx)", low_value, (uint16_t) (value|0xff)); + in_range = 0; + } else { + cil_printf("(range 0x%hx 0x%hx)", value, (uint16_t) (value|0xff)); + } + } + } + + return 0; +} + +static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const class_perm_node_t *classperms, const av_extended_perms_t *xperms) +{ + int rc = -1; + const char *rule; + const struct class_perm_node *classperm; + + switch (type) { + case AVRULE_XPERMS_ALLOWED: + rule = "allowx"; + break; + case AVRULE_XPERMS_AUDITALLOW: + rule = "auditallowx"; + break; + case AVRULE_XPERMS_DONTAUDIT: + rule = "dontauditx"; + break; + case AVRULE_XPERMS_NEVERALLOW: + rule = "neverallowx"; + break; + default: + log_err("Unknown avrule xperm type: %i", type); + rc = -1; + goto exit; + } + + for (classperm = classperms; classperm != NULL; classperm = classperm->next) { + cil_indent(indent); + cil_printf("(%s %s %s (%s %s (", rule, src, tgt, + "ioctl", pdb->p_class_val_to_name[classperm->tclass - 1]); + xperms_to_cil(xperms); + cil_printf(")))\n"); + } + + return 0; + +exit: + return rc; +} + +static unsigned int num_digits(unsigned int n) +{ + unsigned int num = 1; + while (n >= 10) { + n /= 10; + num++; + } + return num; +} + +static int ebitmap_to_cil(struct policydb *pdb, struct ebitmap *map, int type) +{ + struct ebitmap_node *node; + uint32_t i; + char **val_to_name = pdb->sym_val_to_name[type]; + + ebitmap_for_each_positive_bit(map, node, i) { + cil_printf("%s ", val_to_name[i]); + } + + return 0; +} + +static char *get_new_attr_name(struct policydb *pdb, int is_type) +{ + static unsigned int num_attrs = 0; + int len, rlen; + const char *infix; + char *attr_name = NULL; + + num_attrs++; + + if (is_type) { + infix = TYPEATTR_INFIX; + } else { + infix = ROLEATTR_INFIX; + } + + len = strlen(pdb->name) + strlen(infix) + num_digits(num_attrs) + 1; + attr_name = malloc(len); + if (!attr_name) { + log_err("Out of memory"); + goto exit; + } + + rlen = snprintf(attr_name, len, "%s%s%i", pdb->name, infix, num_attrs); + if (rlen < 0 || rlen >= len) { + log_err("Failed to generate attribute name"); + free(attr_name); + attr_name = NULL; + goto exit; + } + +exit: + return attr_name; +} + +static int cil_add_attr_to_list(struct list *attr_list, char *attr_name, int is_type, void *set) +{ + struct attr_list_node *attr_list_node = NULL; + int rc = 0; + + attr_list_node = calloc(1, sizeof(*attr_list_node)); + if (attr_list_node == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + + rc = list_prepend(attr_list, attr_list_node); + if (rc != 0) { + goto exit; + } + + attr_list_node->attr_name = attr_name; + attr_list_node->is_type = is_type; + attr_list_node->set = set; + + return rc; + +exit: + free(attr_list_node); + return rc; +} + +static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, void *set, char *attr_name) +{ + // CIL doesn't support anonymous positive/negative/complemented sets. So + // instead we create a CIL type/roleattributeset that matches the set. If + // the set has a negative set, then convert it to is (P & !N), where P is + // the list of members in the positive set and N is the list of members + // in the negative set. Additionally, if the set is complemented, then wrap + // the whole thing with a negation. + + struct ebitmap_node *node; + struct ebitmap *pos, *neg; + uint32_t flags; + unsigned i; + struct type_set *ts; + struct role_set *rs; + int has_positive, has_negative; + const char *kind; + char **val_to_name; + int rc = 0; + + if (is_type) { + kind = "type"; + val_to_name = pdb->p_type_val_to_name; + ts = (struct type_set *)set; + pos = &ts->types; + neg = &ts->negset; + flags = ts->flags; + has_positive = pos && !ebitmap_is_empty(pos); + has_negative = neg && !ebitmap_is_empty(neg); + } else { + kind = "role"; + val_to_name = pdb->p_role_val_to_name; + rs = (struct role_set *)set; + pos = &rs->roles; + neg = NULL; + flags = rs->flags; + has_positive = pos && !ebitmap_is_empty(pos); + has_negative = 0; + } + + cil_println(indent, "(%sattribute %s)", kind, attr_name); + cil_indent(indent); + cil_printf("(%sattributeset %s ", kind, attr_name); + + if (flags & TYPE_STAR) { + cil_printf("(all)"); + } + + if (flags & TYPE_COMP) { + cil_printf("(not "); + } + + if (has_positive && has_negative) { + cil_printf("(and "); + } + + if (has_positive) { + cil_printf("("); + ebitmap_for_each_positive_bit(pos, node, i) { + cil_printf("%s ", val_to_name[i]); + } + cil_printf(") "); + } + + if (has_negative) { + cil_printf("(not ("); + + ebitmap_for_each_positive_bit(neg, node, i) { + cil_printf("%s ", val_to_name[i]); + } + + cil_printf("))"); + } + + if (has_positive && has_negative) { + cil_printf(")"); + } + + if (flags & TYPE_COMP) { + cil_printf(")"); + } + + cil_printf(")\n"); + + return rc; +} + +static int cil_print_attr_list(int indent, struct policydb *pdb, struct list *attr_list) +{ + struct list_node *curr; + struct attr_list_node *node; + int rc = 0; + + for (curr = attr_list->head; curr != NULL; curr = curr->next) { + node = curr->data; + rc = cil_print_attr_strs(indent, pdb, node->is_type, node->set, node->attr_name); + if (rc != 0) { + return rc; + } + } + + return rc; +} + +static char *search_attr_list(struct list *attr_list, int is_type, void *set) +{ + struct list_node *curr; + struct attr_list_node *node; + struct role_set *rs1 = NULL, *rs2; + struct type_set *ts1 = NULL, *ts2; + + if (is_type) { + ts1 = (struct type_set *)set; + } else { + rs1 = (struct role_set *)set; + } + + for (curr = attr_list->head; curr != NULL; curr = curr->next) { + node = curr->data; + if (node->is_type != is_type) + continue; + if (ts1) { + ts2 = (struct type_set *)node->set; + if (ts1->flags != ts2->flags) + continue; + if (ksu_ebitmap_cmp(&ts1->negset, &ts2->negset) == 0) + continue; + if (ksu_ebitmap_cmp(&ts1->types, &ts2->types) == 0) + continue; + return node->attr_name; + } else { + rs2 = (struct role_set *)node->set; + if (rs1->flags != rs2->flags) + continue; + if (ksu_ebitmap_cmp(&rs1->roles, &rs2->roles) == 0) + continue; + return node->attr_name; + } + } + + return NULL; +} + +static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, unsigned int *num_names) +{ + char *attr_name = NULL; + int rc = 0; + + *names = NULL; + *num_names = 0; + + attr_name = search_attr_list(attr_list, is_type, set); + + if (!attr_name) { + attr_name = get_new_attr_name(pdb, is_type); + if (!attr_name) { + rc = -1; + goto exit; + } + + rc = cil_add_attr_to_list(attr_list, attr_name, is_type, set); + if (rc != 0) { + free(attr_name); + goto exit; + } + } + + *names = malloc(sizeof(char *)); + if (!*names) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + *names[0] = attr_name; + *num_names = 1; + +exit: + return rc; +} + +static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, unsigned int *num_names) +{ + int rc = 0; + struct ebitmap_node *node; + uint32_t i; + unsigned int num; + char **name_arr; + + num = 0; + ebitmap_for_each_positive_bit(map, node, i) { + if (num >= UINT32_MAX / sizeof(*name_arr)) { + log_err("Overflow"); + rc = -1; + goto exit; + } + num++; + } + + if (!num) { + *names = NULL; + *num_names = 0; + goto exit; + } + + name_arr = calloc(num, sizeof(*name_arr)); + if (name_arr == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + + num = 0; + ebitmap_for_each_positive_bit(map, node, i) { + name_arr[num] = vals_to_names[i]; + num++; + } + + *names = name_arr; + *num_names = num; + +exit: + return rc; +} + +static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, unsigned int *num_names) +{ + int rc = 0; + + *names = NULL; + *num_names = 0; + + if (rs->flags) { + rc = set_to_names(pdb, 0, &rs->roles, attr_list, names, num_names); + if (rc != 0) { + goto exit; + } + } else { + rc = ebitmap_to_names(&rs->roles, pdb->p_role_val_to_name, names, num_names); + if (rc != 0) { + goto exit; + } + } + +exit: + return rc; +} + +static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, unsigned int *num_names) +{ + int rc = 0; + + *names = NULL; + *num_names = 0; + + if (!ebitmap_is_empty(&ts->negset) || ts->flags != 0) { + rc = set_to_names(pdb, 1, ts, attr_list, names, num_names); + if (rc != 0) { + goto exit; + } + } else { + rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, names, num_names); + if (rc != 0) { + goto exit; + } + } + +exit: + return rc; +} + +static void names_destroy(char ***names, unsigned int *num_names) +{ + free(*names); + *names = NULL; + *num_names = 0; +} + +static int roletype_role_in_ancestor_to_cil(struct policydb *pdb, struct stack *decl_stack, char *type_name, int indent) +{ + struct list_node *curr; + char **tnames = NULL; + unsigned int num_tnames, i; + struct role_list_node *role_node = NULL; + int rc; + struct type_set *ts; + struct list *attr_list = NULL; + + rc = list_init(&attr_list); + if (rc != 0) { + goto exit; + } + + for (curr = role_list->head; curr != NULL; curr = curr->next) { + role_node = curr->data; + if (!is_id_in_ancestor_scope(pdb, decl_stack, role_node->role_name, SYM_ROLES)) { + continue; + } + + ts = &role_node->role->types; + rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames); + if (rc != 0) { + goto exit; + } + for (i = 0; i < num_tnames; i++) { + if (!strcmp(type_name, tnames[i])) { + cil_println(indent, "(roletype %s %s)", role_node->role_name, type_name); + } + } + names_destroy(&tnames, &num_tnames); + } + + rc = cil_print_attr_list(indent, pdb, attr_list); + if (rc != 0) { + goto exit; + } + +exit: + attr_list_destroy(&attr_list); + return rc; +} + + +static int name_list_to_string(char **names, unsigned int num_names, char **string) +{ + // create a space separated string of the names + int rc = -1; + size_t len = 0; + unsigned int i; + char *str; + char *strpos; + + for (i = 0; i < num_names; i++) { + if (__builtin_add_overflow(len, strlen(names[i]), &len)) { + log_err("Overflow"); + return -1; + } + } + + // add spaces + null terminator + if (__builtin_add_overflow(len, (size_t)num_names, &len)) { + log_err("Overflow"); + return -1; + } + + if (!len) { + log_err("Empty list"); + return -1; + } + + str = malloc(len); + if (str == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + str[0] = 0; + + strpos = str; + + for (i = 0; i < num_names; i++) { + strpos = stpcpy(strpos, names[i]); + if (i < num_names - 1) { + *strpos++ = ' '; + } + } + + *string = str; + + return 0; +exit: + free(str); + return rc; +} + +static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *avrule_list, struct list *attr_list) +{ + int rc = -1; + struct avrule *avrule; + char **snames = NULL; + char **tnames = NULL; + unsigned int s, t, num_snames, num_tnames; + struct type_set *ts; + + for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) { + if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) && + avrule->source_filename) { + cil_println(0, ";;* lmx %lu %s\n",avrule->source_line, avrule->source_filename); + } + + ts = &avrule->stypes; + rc = process_typeset(pdb, ts, attr_list, &snames, &num_snames); + if (rc != 0) { + goto exit; + } + + ts = &avrule->ttypes; + rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames); + if (rc != 0) { + goto exit; + } + + for (s = 0; s < num_snames; s++) { + for (t = 0; t < num_tnames; t++) { + if (avrule->specified & AVRULE_XPERMS) { + rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms, avrule->xperms); + } else { + rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms); + } + if (rc != 0) { + goto exit; + } + } + + if (avrule->flags & RULE_SELF) { + if (avrule->specified & AVRULE_XPERMS) { + rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms, avrule->xperms); + } else { + rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms); + } + if (rc != 0) { + goto exit; + } + } + } + + names_destroy(&snames, &num_snames); + names_destroy(&tnames, &num_tnames); + + if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) && + avrule->source_filename) { + cil_println(0, ";;* lme\n"); + } + } + + return 0; + +exit: + names_destroy(&snames, &num_snames); + names_destroy(&tnames, &num_tnames); + + return rc; +} + +static int cond_expr_to_cil(int indent, struct policydb *pdb, struct cond_expr *cond_expr, uint32_t flags) +{ + int rc = 0; + struct cond_expr *curr; + struct stack *stack = NULL; + int len = 0; + int rlen; + char *new_val = NULL; + char *val1 = NULL; + char *val2 = NULL; + unsigned int num_params; + const char *op; + const char *sep; + const char *type; + + rc = stack_init(&stack); + if (rc != 0) { + log_err("Out of memory"); + goto exit; + } + + for (curr = cond_expr; curr != NULL; curr = curr->next) { + if (curr->expr_type == COND_BOOL) { + val1 = pdb->p_bool_val_to_name[curr->bool - 1]; + // length of boolean + 2 parens + null terminator + len = strlen(val1) + 2 + 1; + new_val = malloc(len); + if (new_val == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + rlen = snprintf(new_val, len, "(%s)", val1); + if (rlen < 0 || rlen >= len) { + log_err("Failed to generate conditional expression"); + rc = -1; + goto exit; + } + } else { + switch(curr->expr_type) { + case COND_NOT: op = "not"; break; + case COND_OR: op = "or"; break; + case COND_AND: op = "and"; break; + case COND_XOR: op = "xor"; break; + case COND_EQ: op = "eq"; break; + case COND_NEQ: op = "neq"; break; + default: + rc = -1; + goto exit; + } + + num_params = curr->expr_type == COND_NOT ? 1 : 2; + + if (num_params == 1) { + val1 = stack_pop(stack); + val2 = strdup(""); + if (val2 == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + sep = ""; + } else { + val2 = stack_pop(stack); + val1 = stack_pop(stack); + sep = " "; + } + + if (val1 == NULL || val2 == NULL) { + log_err("Invalid conditional expression"); + rc = -1; + goto exit; + } + + // length = length of parameters + + // length of operator + + // 1 space preceding each parameter + + // 2 parens around the whole expression + // + null terminator + len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1; + new_val = malloc(len); + if (new_val == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + + rlen = snprintf(new_val, len, "(%s %s%s%s)", op, val1, sep, val2); + if (rlen < 0 || rlen >= len) { + log_err("Failed to generate conditional expression"); + rc = -1; + goto exit; + } + + free(val1); + free(val2); + val1 = NULL; + val2 = NULL; + } + + rc = stack_push(stack, new_val); + if (rc != 0) { + log_err("Out of memory"); + goto exit; + } + new_val = NULL; + } + + if (flags & COND_NODE_FLAGS_TUNABLE) { + type = "tunableif"; + } else { + type = "booleanif"; + } + + val1 = stack_pop(stack); + if (val1 == NULL || stack_peek(stack) != NULL) { + log_err("Invalid conditional expression"); + rc = -1; + goto exit; + } + + cil_println(indent, "(%s %s", type, val1); + free(val1); + val1 = NULL; + + rc = 0; + +exit: + free(new_val); + free(val1); + free(val2); + if (stack != NULL) { + while ((val1 = stack_pop(stack)) != NULL) { + free(val1); + } + stack_destroy(&stack); + } + return rc; +} + +static int cond_list_to_cil(int indent, struct policydb *pdb, struct cond_node *cond_list, struct list *attr_list) +{ + int rc = 0; + struct cond_node *cond; + + for (cond = cond_list; cond != NULL; cond = cond->next) { + + rc = cond_expr_to_cil(indent, pdb, cond->expr, cond->flags); + if (rc != 0) { + goto exit; + } + + if (cond->avtrue_list != NULL) { + cil_println(indent + 1, "(true"); + rc = avrule_list_to_cil(indent + 2, pdb, cond->avtrue_list, attr_list); + if (rc != 0) { + goto exit; + } + cil_println(indent + 1, ")"); + } + + if (cond->avfalse_list != NULL) { + cil_println(indent + 1, "(false"); + rc = avrule_list_to_cil(indent + 2, pdb, cond->avfalse_list, attr_list); + if (rc != 0) { + goto exit; + } + cil_println(indent + 1, ")"); + } + + cil_println(indent, ")"); + } + +exit: + return rc; +} + +static int role_trans_to_cil(int indent, struct policydb *pdb, struct role_trans_rule *rules, struct list *role_attr_list, struct list *type_attr_list) +{ + int rc = 0; + struct role_trans_rule *rule; + char **role_names = NULL; + unsigned int num_role_names = 0; + unsigned int role; + char **type_names = NULL; + unsigned int num_type_names = 0; + unsigned int type; + uint32_t i; + struct ebitmap_node *node; + struct type_set *ts; + struct role_set *rs; + + for (rule = rules; rule != NULL; rule = rule->next) { + rs = &rule->roles; + rc = process_roleset(pdb, rs, role_attr_list, &role_names, &num_role_names); + if (rc != 0) { + goto exit; + } + + ts = &rule->types; + rc = process_typeset(pdb, ts, type_attr_list, &type_names, &num_type_names); + if (rc != 0) { + goto exit; + } + + for (role = 0; role < num_role_names; role++) { + for (type = 0; type < num_type_names; type++) { + ebitmap_for_each_positive_bit(&rule->classes, node, i) { + cil_println(indent, "(roletransition %s %s %s %s)", + role_names[role], type_names[type], + pdb->p_class_val_to_name[i], + pdb->p_role_val_to_name[rule->new_role - 1]); + } + } + } + + names_destroy(&role_names, &num_role_names); + names_destroy(&type_names, &num_type_names); + } + +exit: + names_destroy(&role_names, &num_role_names); + names_destroy(&type_names, &num_type_names); + + return rc; +} + +static int role_allows_to_cil(int indent, struct policydb *pdb, struct role_allow_rule *rules, struct list *attr_list) +{ + int rc = -1; + struct role_allow_rule *rule; + char **roles = NULL; + unsigned int num_roles = 0; + char **new_roles = NULL; + unsigned int num_new_roles = 0; + unsigned int i, j; + struct role_set *rs; + + for (rule = rules; rule != NULL; rule = rule->next) { + rs = &rule->roles; + rc = process_roleset(pdb, rs, attr_list, &roles, &num_roles); + if (rc != 0) { + goto exit; + } + + rs = &rule->new_roles; + rc = process_roleset(pdb, rs, attr_list, &new_roles, &num_new_roles); + if (rc != 0) { + goto exit; + } + + for (i = 0; i < num_roles; i++) { + for (j = 0; j < num_new_roles; j++) { + cil_println(indent, "(roleallow %s %s)", roles[i], new_roles[j]); + } + } + + names_destroy(&roles, &num_roles); + names_destroy(&new_roles, &num_new_roles); + } + + rc = 0; + +exit: + names_destroy(&roles, &num_roles); + names_destroy(&new_roles, &num_new_roles); + + return rc; +} + +static int range_trans_to_cil(int indent, struct policydb *pdb, struct range_trans_rule *rules, struct list *attr_list) +{ + int rc = -1; + struct range_trans_rule *rule; + char **stypes = NULL; + unsigned int num_stypes = 0; + unsigned int stype; + char **ttypes = NULL; + unsigned int num_ttypes = 0; + unsigned int ttype; + struct ebitmap_node *node; + uint32_t i; + struct type_set *ts; + + if (!pdb->mls) { + return 0; + } + + for (rule = rules; rule != NULL; rule = rule->next) { + ts = &rule->stypes; + rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes); + if (rc != 0) { + goto exit; + } + + ts = &rule->ttypes; + rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes); + if (rc != 0) { + goto exit; + } + + for (stype = 0; stype < num_stypes; stype++) { + for (ttype = 0; ttype < num_ttypes; ttype++) { + ebitmap_for_each_positive_bit(&rule->tclasses, node, i) { + cil_indent(indent); + cil_printf("(rangetransition %s %s %s ", stypes[stype], ttypes[ttype], pdb->p_class_val_to_name[i]); + + cil_printf("("); + + rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[0]); + if (rc != 0) { + goto exit; + } + + cil_printf(" "); + + rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[1]); + if (rc != 0) { + goto exit; + } + + cil_printf("))\n"); + } + + } + } + + names_destroy(&stypes, &num_stypes); + names_destroy(&ttypes, &num_ttypes); + } + + rc = 0; + +exit: + names_destroy(&stypes, &num_stypes); + names_destroy(&ttypes, &num_ttypes); + + return rc; +} + +static int filename_trans_to_cil(int indent, struct policydb *pdb, struct filename_trans_rule *rules, struct list *attr_list) +{ + int rc = -1; + char **stypes = NULL; + unsigned int num_stypes = 0; + unsigned int stype; + char **ttypes = NULL; + unsigned int num_ttypes = 0; + unsigned int ttype; + struct type_set *ts; + struct filename_trans_rule *rule; + + for (rule = rules; rule != NULL; rule = rule->next) { + ts = &rule->stypes; + rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes); + if (rc != 0) { + goto exit; + } + + ts = &rule->ttypes; + rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes); + if (rc != 0) { + goto exit; + } + + for (stype = 0; stype < num_stypes; stype++) { + for (ttype = 0; ttype < num_ttypes; ttype++) { + cil_println(indent, "(typetransition %s %s %s \"%s\" %s)", + stypes[stype], ttypes[ttype], + pdb->p_class_val_to_name[rule->tclass - 1], + rule->name, + pdb->p_type_val_to_name[rule->otype - 1]); + } + if (rule->flags & RULE_SELF) { + cil_println(indent, "(typetransition %s self %s \"%s\" %s)", + stypes[stype], + pdb->p_class_val_to_name[rule->tclass - 1], + rule->name, + pdb->p_type_val_to_name[rule->otype - 1]); + } + } + + names_destroy(&stypes, &num_stypes); + names_destroy(&ttypes, &num_ttypes); + } + + rc = 0; +exit: + names_destroy(&stypes, &num_stypes); + names_destroy(&ttypes, &num_ttypes); + + return rc; +} + +struct class_perm_datum { + char *name; + uint32_t val; +}; + +struct class_perm_array { + struct class_perm_datum *perms; + uint32_t count; +}; + +static int class_perm_to_array(char *key, void *data, void *args) +{ + struct class_perm_array *arr = args; + struct perm_datum *datum = data; + arr->perms[arr->count].name = key; + arr->perms[arr->count].val = datum->s.value; + arr->count++; + + return 0; +} + +static int class_perm_cmp(const void *a, const void *b) +{ + const struct class_perm_datum *aa = a; + const struct class_perm_datum *bb = b; + + return aa->val - bb->val; +} + +static int common_to_cil(char *key, void *data, void *UNUSED(arg)) +{ + int rc = -1; + struct common_datum *common = data; + struct class_perm_array arr; + uint32_t i; + + arr.count = 0; + arr.perms = calloc(common->permissions.nprim, sizeof(*arr.perms)); + if (arr.perms == NULL) { + goto exit; + } + rc = ksu_hashtab_map(common->permissions.table, class_perm_to_array, &arr); + if (rc != 0) { + goto exit; + } + + qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp); + + cil_printf("(common %s (", key); + for (i = 0; i < arr.count; i++) { + cil_printf("%s ", arr.perms[i].name); + } + cil_printf("))\n"); + + rc = 0; + +exit: + free(arr.perms); + return rc; +} + + +static int constraint_expr_to_string(struct policydb *pdb, struct constraint_expr *exprs, char **expr_string) +{ + int rc = -1; + struct constraint_expr *expr; + struct stack *stack = NULL; + int len = 0; + int rlen; + char *new_val = NULL; + char *val1 = NULL; + char *val2 = NULL; + uint32_t num_params; + const char *op; + const char *sep; + const char *attr1; + const char *attr2; + char *names = NULL; + char **name_list = NULL; + unsigned int num_names = 0; + struct type_set *ts; + + rc = stack_init(&stack); + if (rc != 0) { + goto exit; + } + + for (expr = exprs; expr != NULL; expr = expr->next) { + if (expr->expr_type == CEXPR_ATTR || expr->expr_type == CEXPR_NAMES) { + switch (expr->op) { + case CEXPR_EQ: op = "eq"; break; + case CEXPR_NEQ: op = "neq"; break; + case CEXPR_DOM: op = "dom"; break; + case CEXPR_DOMBY: op = "domby"; break; + case CEXPR_INCOMP: op = "incomp"; break; + default: + log_err("Unknown constraint operator type: %i", expr->op); + rc = -1; + goto exit; + } + + switch (expr->attr) { + case CEXPR_USER: attr1 = "u1"; attr2 = "u2"; break; + case CEXPR_USER | CEXPR_TARGET: attr1 = "u2"; attr2 = ""; break; + case CEXPR_USER | CEXPR_XTARGET: attr1 = "u3"; attr2 = ""; break; + case CEXPR_ROLE: attr1 = "r1"; attr2 = "r2"; break; + case CEXPR_ROLE | CEXPR_TARGET: attr1 = "r2"; attr2 = ""; break; + case CEXPR_ROLE | CEXPR_XTARGET: attr1 = "r3"; attr2 = ""; break; + case CEXPR_TYPE: attr1 = "t1"; attr2 = "t2"; break; + case CEXPR_TYPE | CEXPR_TARGET: attr1 = "t2"; attr2 = ""; break; + case CEXPR_TYPE | CEXPR_XTARGET: attr1 = "t3"; attr2 = ""; break; + case CEXPR_L1L2: attr1 = "l1"; attr2 = "l2"; break; + case CEXPR_L1H2: attr1 = "l1"; attr2 = "h2"; break; + case CEXPR_H1L2: attr1 = "h1"; attr2 = "l2"; break; + case CEXPR_H1H2: attr1 = "h1"; attr2 = "h2"; break; + case CEXPR_L1H1: attr1 = "l1"; attr2 = "h1"; break; + case CEXPR_L2H2: attr1 = "l2"; attr2 = "h2"; break; + default: + log_err("Unknown expression attribute type: %i", expr->attr); + rc = -1; + goto exit; + } + + if (expr->expr_type == CEXPR_ATTR) { + // length of values/attrs + 2 separating spaces + 2 parens + null terminator + len = strlen(op) + strlen(attr1) + strlen(attr2) + 2 + 2 + 1; + new_val = malloc(len); + if (new_val == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, attr2); + if (rlen < 0 || rlen >= len) { + log_err("Failed to generate constraint expression"); + rc = -1; + goto exit; + } + } else { + if (expr->attr & CEXPR_TYPE) { + ts = expr->type_names; + rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, &name_list, &num_names); + if (rc != 0) { + goto exit; + } + } else if (expr->attr & CEXPR_USER) { + rc = ebitmap_to_names(&expr->names, pdb->p_user_val_to_name, &name_list, &num_names); + if (rc != 0) { + goto exit; + } + } else if (expr->attr & CEXPR_ROLE) { + rc = ebitmap_to_names(&expr->names, pdb->p_role_val_to_name, &name_list, &num_names); + if (rc != 0) { + goto exit; + } + } + if (num_names == 0) { + names = strdup("NO_IDENTIFIER"); + if (!names) { + rc = -1; + goto exit; + } + } else { + rc = name_list_to_string(name_list, num_names, &names); + if (rc != 0) { + goto exit; + } + } + + // length of values/oper + 2 spaces + 2 parens + null terminator + len = strlen(op) + strlen(attr1) + strlen(names) + 2 + 2 + 1; + if (num_names > 1) { + len += 2; // 2 more parens + } + new_val = malloc(len); + if (new_val == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + if (num_names > 1) { + rlen = snprintf(new_val, len, "(%s %s (%s))", op, attr1, names); + } else { + rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names); + } + if (rlen < 0 || rlen >= len) { + log_err("Failed to generate constraint expression"); + rc = -1; + goto exit; + } + + names_destroy(&name_list, &num_names); + free(names); + names = NULL; + } + } else { + switch (expr->expr_type) { + case CEXPR_NOT: op = "not"; break; + case CEXPR_AND: op = "and"; break; + case CEXPR_OR: op = "or"; break; + default: + log_err("Unknown constraint expression type: %i", expr->expr_type); + rc = -1; + goto exit; + } + + num_params = expr->expr_type == CEXPR_NOT ? 1 : 2; + + if (num_params == 1) { + val1 = stack_pop(stack); + val2 = strdup(""); + if (val2 == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + sep = ""; + } else { + val2 = stack_pop(stack); + val1 = stack_pop(stack); + sep = " "; + } + + if (val1 == NULL || val2 == NULL) { + log_err("Invalid constraint expression"); + rc = -1; + goto exit; + } + + // length = length of parameters + + // length of operator + + // 1 space preceding each parameter + + // 2 parens around the whole expression + // + null terminator + len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1; + new_val = malloc(len); + if (new_val == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + + rlen = snprintf(new_val, len, "(%s %s%s%s)", op, val1, sep, val2); + if (rlen < 0 || rlen >= len) { + log_err("Failed to generate constraint expression"); + rc = -1; + goto exit; + } + + free(val1); + free(val2); + val1 = NULL; + val2 = NULL; + } + + rc = stack_push(stack, new_val); + if (rc != 0) { + log_err("Out of memory"); + goto exit; + } + + new_val = NULL; + } + + new_val = stack_pop(stack); + if (new_val == NULL || stack_peek(stack) != NULL) { + log_err("Invalid constraint expression"); + rc = -1; + goto exit; + } + + *expr_string = new_val; + new_val = NULL; + + rc = 0; + +exit: + names_destroy(&name_list, &num_names); + free(names); + + free(new_val); + free(val1); + free(val2); + if (stack != NULL) { + while ((val1 = stack_pop(stack)) != NULL) { + free(val1); + } + stack_destroy(&stack); + } + + return rc; +} + + +static int constraints_to_cil(int indent, struct policydb *pdb, char *classkey, struct class_datum *class, struct constraint_node *constraints, int is_constraint) +{ + int rc = -1; + struct constraint_node *node; + char *expr = NULL; + const char *mls; + char *perms; + + mls = pdb->mls ? "mls" : ""; + + for (node = constraints; node != NULL; node = node->next) { + + rc = constraint_expr_to_string(pdb, node->expr, &expr); + if (rc != 0) { + goto exit; + } + + if (is_constraint) { + perms = sepol_av_to_string(pdb, class->s.value, node->permissions); + cil_println(indent, "(%sconstrain (%s (%s)) %s)", mls, classkey, perms + 1, expr); + } else { + cil_println(indent, "(%svalidatetrans %s %s)", mls, classkey, expr); + } + + free(expr); + expr = NULL; + } + + rc = 0; + +exit: + free(expr); + return rc; +} + +static int class_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) +{ + int rc = -1; + struct class_datum *class = datum; + const char *dflt; + struct class_perm_array arr; + uint32_t i; + + if (scope == SCOPE_REQ) { + return 0; + } + + arr.count = 0; + arr.perms = calloc(class->permissions.nprim, sizeof(*arr.perms)); + if (arr.perms == NULL) { + goto exit; + } + rc = ksu_hashtab_map(class->permissions.table, class_perm_to_array, &arr); + if (rc != 0) { + goto exit; + } + + qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp); + + cil_indent(indent); + cil_printf("(class %s (", key); + for (i = 0; i < arr.count; i++) { + cil_printf("%s ", arr.perms[i].name); + } + cil_printf("))\n"); + + if (class->comkey != NULL) { + cil_println(indent, "(classcommon %s %s)", key, class->comkey); + } + + if (class->default_user != 0) { + switch (class->default_user) { + case DEFAULT_SOURCE: dflt = "source"; break; + case DEFAULT_TARGET: dflt = "target"; break; + default: + log_err("Unknown default user value: %i", class->default_user); + rc = -1; + goto exit; + } + cil_println(indent, "(defaultuser %s %s)", key, dflt); + } + + if (class->default_role != 0) { + switch (class->default_role) { + case DEFAULT_SOURCE: dflt = "source"; break; + case DEFAULT_TARGET: dflt = "target"; break; + default: + log_err("Unknown default role value: %i", class->default_role); + rc = -1; + goto exit; + } + cil_println(indent, "(defaultrole %s %s)", key, dflt); + } + + if (class->default_type != 0) { + switch (class->default_type) { + case DEFAULT_SOURCE: dflt = "source"; break; + case DEFAULT_TARGET: dflt = "target"; break; + default: + log_err("Unknown default type value: %i", class->default_type); + rc = -1; + goto exit; + } + cil_println(indent, "(defaulttype %s %s)", key, dflt); + } + + if (class->default_range != 0) { + switch (class->default_range) { + case DEFAULT_SOURCE_LOW: dflt = "source low"; break; + case DEFAULT_SOURCE_HIGH: dflt = "source high"; break; + case DEFAULT_SOURCE_LOW_HIGH: dflt = "source low-high"; break; + case DEFAULT_TARGET_LOW: dflt = "target low"; break; + case DEFAULT_TARGET_HIGH: dflt = "target high"; break; + case DEFAULT_TARGET_LOW_HIGH: dflt = "target low-high"; break; + case DEFAULT_GLBLUB: dflt = "glblub"; break; + default: + log_err("Unknown default range value: %i", class->default_range); + rc = -1; + goto exit; + } + cil_println(indent, "(defaultrange %s %s)", key, dflt); + + } + + if (class->constraints != NULL) { + rc = constraints_to_cil(indent, pdb, key, class, class->constraints, 1); + if (rc != 0) { + goto exit; + } + } + + if (class->validatetrans != NULL) { + rc = constraints_to_cil(indent, pdb, key, class, class->validatetrans, 0); + if (rc != 0) { + goto exit; + } + } + + rc = 0; + +exit: + free(arr.perms); + return rc; +} + +static int class_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order) +{ + struct ebitmap_node *node; + uint32_t i; + + if (ebitmap_is_empty(&order)) { + return 0; + } + + cil_indent(indent); + cil_printf("(classorder ("); + + ebitmap_for_each_positive_bit(&order, node, i) { + cil_printf("%s ", pdb->sym_val_to_name[SYM_CLASSES][i]); + } + + cil_printf("))\n"); + + return 0; +} + +static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope) +{ + int rc = -1; + struct ebitmap_node *node; + uint32_t i; + unsigned int j; + char **types = NULL; + unsigned int num_types = 0; + struct role_datum *role = datum; + struct type_set *ts; + struct list *attr_list = NULL; + + rc = list_init(&attr_list); + if (rc != 0) { + goto exit; + } + + if (scope == SCOPE_REQ) { + // if a role/roleattr is in the REQ scope, then it could cause an + // optional block to fail, even if it is never used. However in CIL, + // symbols must be used in order to cause an optional block to fail. So + // for symbols in the REQ scope, add them to a roleattribute as a way + // to 'use' them in the optional without affecting the resulting policy. + cil_println(indent, "(roleattributeset " GEN_REQUIRE_ATTR " %s)", key); + } + + switch (role->flavor) { + case ROLE_ROLE: + if (scope == SCOPE_DECL) { + // Only declare certain roles if we are reading a base module. + // These roles are defined in the base module and sometimes in + // other non-base modules. If we generated the roles regardless of + // the policy type, it would result in duplicate declarations, + // which isn't allowed in CIL. Patches have been made to refpolicy + // to remove these duplicate role declarations, but we need to be + // backwards compatible and support older policies. Since we know + // these roles are always declared in base, only print them when we + // see them in the base module. If the declarations appear in a + // non-base module, ignore their declarations. + // + // Note that this is a hack, and if a policy author does not define + // one of these roles in base, the declaration will not appear in + // the resulting policy, likely resulting in a compilation error in + // CIL. + // + // To make things more complicated, the auditadm_r and secadm_r + // roles could actually be in either the base module or a non-base + // module, or both. So we can't rely on this same behavior. So for + // these roles, don't declare them here, even if they are in a base + // or non-base module. Instead we will just declare them in the + // base module elsewhere. + int is_base_role = (!strcmp(key, "user_r") || + !strcmp(key, "staff_r") || + !strcmp(key, "sysadm_r") || + !strcmp(key, "system_r") || + !strcmp(key, "unconfined_r")); + int is_builtin_role = (!strcmp(key, "auditadm_r") || + !strcmp(key, "secadm_r")); + if ((is_base_role && pdb->policy_type == SEPOL_POLICY_BASE) || + (!is_base_role && !is_builtin_role)) { + cil_println(indent, "(role %s)", key); + } + } + + if (ebitmap_cardinality(&role->dominates) > 1) { + log_err("Warning: role 'dominance' statement unsupported in CIL. Dropping from output."); + } + + ts = &role->types; + rc = process_typeset(pdb, ts, attr_list, &types, &num_types); + if (rc != 0) { + goto exit; + } + + for (j = 0; j < num_types; j++) { + if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) { + cil_println(indent, "(roletype %s %s)", key, types[j]); + } + } + + if (role->bounds > 0) { + cil_println(indent, "(rolebounds %s %s)", key, pdb->p_role_val_to_name[role->bounds - 1]); + } + break; + + case ROLE_ATTRIB: + if (scope == SCOPE_DECL) { + cil_println(indent, "(roleattribute %s)", key); + } + + if (!ebitmap_is_empty(&role->roles)) { + cil_indent(indent); + cil_printf("(roleattributeset %s (", key); + ebitmap_for_each_positive_bit(&role->roles, node, i) { + cil_printf("%s ", pdb->p_role_val_to_name[i]); + } + cil_printf("))\n"); + } + + ts = &role->types; + rc = process_typeset(pdb, ts, attr_list, &types, &num_types); + if (rc != 0) { + goto exit; + } + + + for (j = 0; j < num_types; j++) { + if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) { + cil_println(indent, "(roletype %s %s)", key, types[j]); + } + } + + break; + + default: + log_err("Unknown role type: %i", role->flavor); + rc = -1; + goto exit; + } + + rc = cil_print_attr_list(indent, pdb, attr_list); + if (rc != 0) { + goto exit; + } + +exit: + attr_list_destroy(&attr_list); + names_destroy(&types, &num_types); + + return rc; +} + +static int type_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope) +{ + int rc = -1; + struct type_datum *type = datum; + + if (scope == SCOPE_REQ) { + // if a type/typeattr is in the REQ scope, then it could cause an + // optional block to fail, even if it is never used. However in CIL, + // symbols must be used in order to cause an optional block to fail. So + // for symbols in the REQ scope, add them to a typeattribute as a way + // to 'use' them in the optional without affecting the resulting policy. + cil_println(indent, "(typeattributeset " GEN_REQUIRE_ATTR " %s)", key); + } + + rc = roletype_role_in_ancestor_to_cil(pdb, decl_stack, key, indent); + if (rc != 0) { + goto exit; + } + + switch(type->flavor) { + case TYPE_TYPE: + if (scope == SCOPE_DECL) { + cil_println(indent, "(type %s)", key); + // object_r is implicit in checkmodule, but not with CIL, + // create it as part of base + cil_println(indent, "(roletype " DEFAULT_OBJECT " %s)", key); + } + + if (type->flags & TYPE_FLAGS_PERMISSIVE) { + cil_println(indent, "(typepermissive %s)", key); + } + + if (type->bounds > 0) { + cil_println(indent, "(typebounds %s %s)", pdb->p_type_val_to_name[type->bounds - 1], key); + } + break; + case TYPE_ATTRIB: + if (scope == SCOPE_DECL) { + cil_println(indent, "(typeattribute %s)", key); + } + + if (type->flags & TYPE_FLAGS_EXPAND_ATTR) { + cil_indent(indent); + cil_printf("(expandtypeattribute (%s) ", key); + if (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE) { + cil_printf("true"); + } else if (type->flags & TYPE_FLAGS_EXPAND_ATTR_FALSE) { + cil_printf("false"); + } + cil_printf(")\n"); + } + + if (!ebitmap_is_empty(&type->types)) { + cil_indent(indent); + cil_printf("(typeattributeset %s (", key); + ebitmap_to_cil(pdb, &type->types, SYM_TYPES); + cil_printf("))\n"); + } + break; + case TYPE_ALIAS: + break; + default: + log_err("Unknown flavor (%i) of type %s", type->flavor, key); + rc = -1; + goto exit; + } + + rc = 0; + +exit: + return rc; +} + +static int user_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) +{ + struct user_datum *user = datum; + struct ebitmap roles = user->roles.roles; + struct mls_semantic_level level = user->dfltlevel; + struct mls_semantic_range range = user->range; + struct ebitmap_node *node; + uint32_t i; + int sens_offset = 1; + + if (scope == SCOPE_DECL) { + cil_println(indent, "(user %s)", key); + // object_r is implicit in checkmodule, but not with CIL, create it + // as part of base + cil_println(indent, "(userrole %s " DEFAULT_OBJECT ")", key); + } + + ebitmap_for_each_positive_bit(&roles, node, i) { + cil_println(indent, "(userrole %s %s)", key, pdb->p_role_val_to_name[i]); + } + + if (block->flags & AVRULE_OPTIONAL) { + // sensitivites in user statements in optionals do not have the + // standard -1 offset + sens_offset = 0; + } + + cil_indent(indent); + cil_printf("(userlevel %s ", key); + if (pdb->mls) { + semantic_level_to_cil(pdb, sens_offset, &level); + } else { + cil_printf(DEFAULT_LEVEL); + } + cil_printf(")\n"); + + cil_indent(indent); + cil_printf("(userrange %s (", key); + if (pdb->mls) { + semantic_level_to_cil(pdb, sens_offset, &range.level[0]); + cil_printf(" "); + semantic_level_to_cil(pdb, sens_offset, &range.level[1]); + } else { + cil_printf(DEFAULT_LEVEL " " DEFAULT_LEVEL); + } + cil_printf("))\n"); + + + return 0; +} + +static int boolean_to_cil(int indent, struct policydb *UNUSED(pdb), struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) +{ + struct cond_bool_datum *boolean = datum; + const char *type; + + if (scope == SCOPE_DECL) { + if (boolean->flags & COND_BOOL_FLAGS_TUNABLE) { + type = "tunable"; + } else { + type = "boolean"; + } + + cil_println(indent, "(%s %s %s)", type, key, boolean->state ? "true" : "false"); + } + + return 0; +} + +static int sens_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) +{ + struct level_datum *level = datum; + + if (scope == SCOPE_DECL) { + if (!level->isalias) { + cil_println(indent, "(sensitivity %s)", key); + } else { + cil_println(indent, "(sensitivityalias %s)", key); + cil_println(indent, "(sensitivityaliasactual %s %s)", key, pdb->p_sens_val_to_name[level->level->sens - 1]); + } + } + + if (!ebitmap_is_empty(&level->level->cat)) { + cil_indent(indent); + cil_printf("(sensitivitycategory %s (", key); + ebitmap_to_cil(pdb, &level->level->cat, SYM_CATS); + cil_printf("))\n"); + } + + return 0; +} + +static int sens_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order) +{ + struct ebitmap_node *node; + uint32_t i; + + if (ebitmap_is_empty(&order)) { + return 0; + } + + cil_indent(indent); + cil_printf("(sensitivityorder ("); + + ebitmap_for_each_positive_bit(&order, node, i) { + cil_printf("%s ", pdb->p_sens_val_to_name[i]); + } + + cil_printf("))\n"); + + return 0; +} + +static int cat_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) +{ + struct cat_datum *cat = datum; + + if (scope == SCOPE_REQ) { + return 0; + } + + if (!cat->isalias) { + cil_println(indent, "(category %s)", key); + } else { + cil_println(indent, "(categoryalias %s)", key); + cil_println(indent, "(categoryaliasactual %s %s)", key, pdb->p_cat_val_to_name[cat->s.value - 1]); + } + + return 0; +} + +static int cat_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order) +{ + int rc = -1; + struct ebitmap_node *node; + uint32_t i; + + if (ebitmap_is_empty(&order)) { + rc = 0; + goto exit; + } + + cil_indent(indent); + cil_printf("(categoryorder ("); + + ebitmap_for_each_positive_bit(&order, node, i) { + cil_printf("%s ", pdb->p_cat_val_to_name[i]); + } + + cil_printf("))\n"); + + return 0; +exit: + return rc; +} + +static int polcaps_to_cil(struct policydb *pdb) +{ + int rc = -1; + struct ebitmap *map; + struct ebitmap_node *node; + uint32_t i; + const char *name; + + map = &pdb->policycaps; + + ebitmap_for_each_positive_bit(map, node, i) { + name = sepol_polcap_getname(i); + if (name == NULL) { + log_err("Unknown policy capability id: %i", i); + rc = -1; + goto exit; + } + + cil_println(0, "(policycap %s)", name); + } + + return 0; +exit: + return rc; +} + +static int level_to_cil(struct policydb *pdb, struct mls_level *level) +{ + struct ebitmap *map = &level->cat; + + cil_printf("(%s", pdb->p_sens_val_to_name[level->sens - 1]); + + if (!ebitmap_is_empty(map)) { + cil_printf("("); + ebitmap_to_cil(pdb, map, SYM_CATS); + cil_printf(")"); + } + + cil_printf(")"); + + return 0; +} + +static int context_to_cil(struct policydb *pdb, struct context_struct *con) +{ + cil_printf("(%s %s %s (", + pdb->p_user_val_to_name[con->user - 1], + pdb->p_role_val_to_name[con->role - 1], + pdb->p_type_val_to_name[con->type - 1]); + + if (pdb->mls) { + level_to_cil(pdb, &con->range.level[0]); + cil_printf(" "); + level_to_cil(pdb, &con->range.level[1]); + } else { + cil_printf(DEFAULT_LEVEL); + cil_printf(" "); + cil_printf(DEFAULT_LEVEL); + } + + cil_printf("))"); + + return 0; +} + +static int ocontext_isid_to_cil(struct policydb *pdb, const char *const *sid_to_string, + unsigned num_sids, struct ocontext *isids) +{ + int rc = -1; + + struct ocontext *isid; + + struct sid_item { + char *sid_key; + struct sid_item *next; + }; + + struct sid_item *head = NULL; + struct sid_item *item = NULL; + char *sid; + char unknown[18]; + unsigned i; + + for (isid = isids; isid != NULL; isid = isid->next) { + i = isid->sid[0]; + if (i < num_sids) { + sid = (char*)sid_to_string[i]; + } else { + snprintf(unknown, 18, "%s%u", "UNKNOWN", i); + sid = unknown; + } + cil_println(0, "(sid %s)", sid); + cil_printf("(sidcontext %s ", sid); + context_to_cil(pdb, &isid->context[0]); + cil_printf(")\n"); + + // get the sid names in the correct order (reverse from the isids + // ocontext) for sidorder statement + item = malloc(sizeof(*item)); + if (item == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + item->sid_key = strdup(sid); + if (!item->sid_key) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + item->next = head; + head = item; + } + + if (head != NULL) { + cil_printf("(sidorder ("); + for (item = head; item != NULL; item = item->next) { + cil_printf("%s ", item->sid_key); + } + cil_printf("))\n"); + } + + rc = 0; + +exit: + while(head) { + item = head; + head = item->next; + free(item->sid_key); + free(item); + } + return rc; +} + +static int ocontext_selinux_isid_to_cil(struct policydb *pdb, struct ocontext *isids) +{ + int rc = -1; + + rc = ocontext_isid_to_cil(pdb, selinux_sid_to_str, SELINUX_SID_SZ, isids); + if (rc != 0) { + goto exit; + } + + return 0; + +exit: + return rc; +} + +static int ocontext_selinux_fs_to_cil(struct policydb *UNUSED(pdb), struct ocontext *fss) +{ + if (fss != NULL) { + log_err("Warning: 'fscon' statement unsupported in CIL. Dropping from output."); + } + + return 0; +} + +static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *portcons) +{ + int rc = -1; + struct ocontext *portcon; + const char *protocol; + uint16_t high; + uint16_t low; + + for (portcon = portcons; portcon != NULL; portcon = portcon->next) { + + switch (portcon->u.port.protocol) { + case IPPROTO_TCP: protocol = "tcp"; break; + case IPPROTO_UDP: protocol = "udp"; break; + case IPPROTO_DCCP: protocol = "dccp"; break; + case IPPROTO_SCTP: protocol = "sctp"; break; + default: + log_err("Unknown portcon protocol: %i", portcon->u.port.protocol); + rc = -1; + goto exit; + } + + low = portcon->u.port.low_port; + high = portcon->u.port.high_port; + + if (low == high) { + cil_printf("(portcon %s %i ", protocol, low); + } else { + cil_printf("(portcon %s (%i %i) ", protocol, low, high); + } + + context_to_cil(pdb, &portcon->context[0]); + + cil_printf(")\n"); + } + + return 0; +exit: + return rc; +} + +static int ocontext_selinux_ibpkey_to_cil(struct policydb *pdb, + struct ocontext *ibpkeycons) +{ + int rc = -1; + struct ocontext *ibpkeycon; + char subnet_prefix_str[INET6_ADDRSTRLEN]; + struct in6_addr subnet_prefix = IN6ADDR_ANY_INIT; + uint16_t high; + uint16_t low; + + for (ibpkeycon = ibpkeycons; ibpkeycon; ibpkeycon = ibpkeycon->next) { + low = ibpkeycon->u.ibpkey.low_pkey; + high = ibpkeycon->u.ibpkey.high_pkey; + memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix, + sizeof(ibpkeycon->u.ibpkey.subnet_prefix)); + + if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, + subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { + log_err("ibpkeycon subnet_prefix is invalid: %m"); + rc = -1; + goto exit; + } + + if (low == high) + cil_printf("(ibpkeycon %s %i ", subnet_prefix_str, low); + else + cil_printf("(ibpkeycon %s (%i %i) ", subnet_prefix_str, low, + high); + + context_to_cil(pdb, &ibpkeycon->context[0]); + + cil_printf(")\n"); + } + return 0; +exit: + return rc; +} + +static int ocontext_selinux_netif_to_cil(struct policydb *pdb, struct ocontext *netifs) +{ + struct ocontext *netif; + + for (netif = netifs; netif != NULL; netif = netif->next) { + cil_printf("(netifcon %s ", netif->u.name); + context_to_cil(pdb, &netif->context[0]); + + cil_printf(" "); + context_to_cil(pdb, &netif->context[1]); + cil_printf(")\n"); + } + + return 0; +} + +static int ocontext_selinux_node_to_cil(struct policydb *pdb, struct ocontext *nodes) +{ + int rc = -1; + struct ocontext *node; + char addr[INET_ADDRSTRLEN]; + char mask[INET_ADDRSTRLEN]; + + for (node = nodes; node != NULL; node = node->next) { + if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { + log_err("Nodecon address is invalid: %m"); + rc = -1; + goto exit; + } + + if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { + log_err("Nodecon mask is invalid: %m"); + rc = -1; + goto exit; + } + + cil_printf("(nodecon (%s) (%s) ", addr, mask); + + context_to_cil(pdb, &node->context[0]); + + cil_printf(")\n"); + } + + return 0; +exit: + return rc; +} + +static int ocontext_selinux_node6_to_cil(struct policydb *pdb, struct ocontext *nodes) +{ + int rc = -1; + struct ocontext *node; + char addr[INET6_ADDRSTRLEN]; + char mask[INET6_ADDRSTRLEN]; + + for (node = nodes; node != NULL; node = node->next) { + if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { + log_err("Nodecon address is invalid: %m"); + rc = -1; + goto exit; + } + + if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { + log_err("Nodecon mask is invalid: %m"); + rc = -1; + goto exit; + } + + cil_printf("(nodecon (%s) (%s) ", addr, mask); + + context_to_cil(pdb, &node->context[0]); + + cil_printf(")\n"); + } + + return 0; +exit: + return rc; +} + +static int ocontext_selinux_ibendport_to_cil(struct policydb *pdb, struct ocontext *ibendports) +{ + struct ocontext *ibendport; + + for (ibendport = ibendports; ibendport; ibendport = ibendport->next) { + cil_printf("(ibendportcon %s %u ", ibendport->u.ibendport.dev_name, ibendport->u.ibendport.port); + context_to_cil(pdb, &ibendport->context[0]); + + cil_printf(")\n"); + } + + return 0; +} + +static int ocontext_selinux_fsuse_to_cil(struct policydb *pdb, struct ocontext *fsuses) +{ + int rc = -1; + struct ocontext *fsuse; + const char *behavior; + + + for (fsuse = fsuses; fsuse != NULL; fsuse = fsuse->next) { + switch (fsuse->v.behavior) { + case SECURITY_FS_USE_XATTR: behavior = "xattr"; break; + case SECURITY_FS_USE_TRANS: behavior = "trans"; break; + case SECURITY_FS_USE_TASK: behavior = "task"; break; + default: + log_err("Unknown fsuse behavior: %i", fsuse->v.behavior); + rc = -1; + goto exit; + } + + cil_printf("(fsuse %s %s ", behavior, fsuse->u.name); + + context_to_cil(pdb, &fsuse->context[0]); + + cil_printf(")\n"); + + } + + return 0; +exit: + return rc; +} + + +static int ocontext_xen_isid_to_cil(struct policydb *pdb, struct ocontext *isids) +{ + int rc = -1; + + rc = ocontext_isid_to_cil(pdb, xen_sid_to_str, XEN_SID_SZ, isids); + if (rc != 0) { + goto exit; + } + + return 0; + +exit: + return rc; +} + +static int ocontext_xen_pirq_to_cil(struct policydb *pdb, struct ocontext *pirqs) +{ + struct ocontext *pirq; + + for (pirq = pirqs; pirq != NULL; pirq = pirq->next) { + cil_printf("(pirqcon %i ", pirq->u.pirq); + context_to_cil(pdb, &pirq->context[0]); + cil_printf(")\n"); + } + + return 0; +} + +static int ocontext_xen_ioport_to_cil(struct policydb *pdb, struct ocontext *ioports) +{ + struct ocontext *ioport; + uint32_t low; + uint32_t high; + + for (ioport = ioports; ioport != NULL; ioport = ioport->next) { + low = ioport->u.ioport.low_ioport; + high = ioport->u.ioport.high_ioport; + + if (low == high) { + cil_printf("(ioportcon 0x%x ", low); + } else { + cil_printf("(ioportcon (0x%x 0x%x) ", low, high); + } + + context_to_cil(pdb, &ioport->context[0]); + + cil_printf(")\n"); + } + + return 0; +} + +static int ocontext_xen_iomem_to_cil(struct policydb *pdb, struct ocontext *iomems) +{ + struct ocontext *iomem; + uint64_t low; + uint64_t high; + + for (iomem = iomems; iomem != NULL; iomem = iomem->next) { + low = iomem->u.iomem.low_iomem; + high = iomem->u.iomem.high_iomem; + + if (low == high) { + cil_printf("(iomemcon 0x%"PRIx64" ", low); + } else { + cil_printf("(iomemcon (0x%"PRIx64" 0x%"PRIx64") ", low, high); + } + + context_to_cil(pdb, &iomem->context[0]); + + cil_printf(")\n"); + } + + return 0; +} + +static int ocontext_xen_pcidevice_to_cil(struct policydb *pdb, struct ocontext *pcids) +{ + struct ocontext *pcid; + + for (pcid = pcids; pcid != NULL; pcid = pcid->next) { + cil_printf("(pcidevicecon 0x%lx ", (unsigned long)pcid->u.device); + context_to_cil(pdb, &pcid->context[0]); + cil_printf(")\n"); + } + + return 0; +} + +static int ocontexts_to_cil(struct policydb *pdb) +{ + int rc = -1; + int ocon; + + static int (**ocon_funcs)(struct policydb *pdb, struct ocontext *ocon); + static int (*ocon_selinux_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = { + ocontext_selinux_isid_to_cil, + ocontext_selinux_fs_to_cil, + ocontext_selinux_port_to_cil, + ocontext_selinux_netif_to_cil, + ocontext_selinux_node_to_cil, + ocontext_selinux_fsuse_to_cil, + ocontext_selinux_node6_to_cil, + ocontext_selinux_ibpkey_to_cil, + ocontext_selinux_ibendport_to_cil, + }; + static int (*ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = { + ocontext_xen_isid_to_cil, + ocontext_xen_pirq_to_cil, + ocontext_xen_ioport_to_cil, + ocontext_xen_iomem_to_cil, + ocontext_xen_pcidevice_to_cil, + NULL, + NULL, + }; + + switch (pdb->target_platform) { + case SEPOL_TARGET_SELINUX: + ocon_funcs = ocon_selinux_funcs; + break; + case SEPOL_TARGET_XEN: + ocon_funcs = ocon_xen_funcs; + break; + default: + log_err("Unknown target platform: %i", pdb->target_platform); + rc = -1; + goto exit; + } + + for (ocon = 0; ocon < OCON_NUM; ocon++) { + if (ocon_funcs[ocon] != NULL) { + rc = ocon_funcs[ocon](pdb, pdb->ocontexts[ocon]); + if (rc != 0) { + goto exit; + } + } + } + + return 0; +exit: + return rc; +} + +static int genfscon_to_cil(struct policydb *pdb) +{ + struct genfs *genfs; + struct ocontext *ocon; + uint32_t sclass; + + for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) { + for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) { + sclass = ocon->v.sclass; + if (sclass) { + const char *file_type; + const char *class_name = pdb->p_class_val_to_name[sclass-1]; + if (strcmp(class_name, "file") == 0) { + file_type = "file"; + } else if (strcmp(class_name, "dir") == 0) { + file_type = "dir"; + } else if (strcmp(class_name, "chr_file") == 0) { + file_type = "char"; + } else if (strcmp(class_name, "blk_file") == 0) { + file_type = "block"; + } else if (strcmp(class_name, "sock_file") == 0) { + file_type = "socket"; + } else if (strcmp(class_name, "fifo_file") == 0) { + file_type = "pipe"; + } else if (strcmp(class_name, "lnk_file") == 0) { + file_type = "symlink"; + } else { + return -1; + } + cil_printf("(genfscon %s \"%s\" %s ", genfs->fstype, ocon->u.name, file_type); + } else { + cil_printf("(genfscon %s \"%s\" ", genfs->fstype, ocon->u.name); + } + context_to_cil(pdb, &ocon->context[0]); + cil_printf(")\n"); + } + } + + return 0; +} + +static int level_string_to_cil(char *levelstr) +{ + int rc = -1; + char *sens = NULL; + char *cats = NULL; + int matched; + char *saveptr = NULL; + char *token = NULL; + char *ranged = NULL; + + matched = tokenize(levelstr, ':', 2, &sens, &cats); + if (matched < 1 || matched > 2) { + log_err("Invalid level: %s", levelstr); + rc = -1; + goto exit; + } + + cil_printf("(%s", sens); + + if (matched == 2) { + cil_printf("("); + token = strtok_r(cats, ",", &saveptr); + while (token != NULL) { + ranged = strchr(token, '.'); + if (ranged == NULL) { + cil_printf("%s ", token); + } else { + *ranged = '\0'; + cil_printf("(range %s %s) ", token, ranged + 1); + } + token = strtok_r(NULL, ",", &saveptr); + } + cil_printf(")"); + } + + cil_printf(")"); + + rc = 0; +exit: + free(sens); + free(cats); + return rc; +} + +static int level_range_string_to_cil(char *levelrangestr) +{ + char *ranged = NULL; + char *low; + char *high; + + ranged = strchr(levelrangestr, '-'); + if (ranged == NULL) { + low = high = levelrangestr; + } else { + *ranged = '\0'; + low = levelrangestr; + high = ranged + 1; + } + + level_string_to_cil(low); + cil_printf(" "); + level_string_to_cil(high); + + return 0; +} + +static int context_string_to_cil(char *contextstr) +{ + int rc = -1; + int matched; + char *user = NULL; + char *role = NULL; + char *type = NULL; + char *level = NULL; + + matched = tokenize(contextstr, ':', 4, &user, &role, &type, &level); + if (matched < 3 || matched > 4) { + log_err("Invalid context: %s", contextstr); + rc = -1; + goto exit; + } + + cil_printf("(%s %s %s (", user, role, type); + + if (matched == 3) { + cil_printf(DEFAULT_LEVEL); + cil_printf(" "); + cil_printf(DEFAULT_LEVEL); + } else { + level_range_string_to_cil(level); + } + + cil_printf("))"); + + rc = 0; + +exit: + free(user); + free(role); + free(type); + free(level); + + return rc; +} + +static int seusers_to_cil(struct sepol_module_package *mod_pkg) +{ + int rc = -1; + char *seusers = sepol_module_package_get_seusers(mod_pkg); + size_t seusers_len = sepol_module_package_get_seusers_len(mod_pkg); + char *cur = seusers; + char *end = seusers + seusers_len; + char *line = NULL; + char *user = NULL; + char *seuser = NULL; + char *level = NULL; + char *tmp = NULL; + int matched; + + if (seusers_len == 0) { + return 0; + } + + while ((rc = get_line(&cur, end, &line)) > 0) { + tmp = line; + while (isspace(*tmp)) { + tmp++; + } + + if (tmp[0] == '#' || tmp[0] == '\0') { + free(line); + line = NULL; + continue; + } + + matched = tokenize(tmp, ':', 3, &user, &seuser, &level); + + if (matched < 2 || matched > 3) { + log_err("Invalid seuser line: %s", line); + rc = -1; + goto exit; + } + + if (!strcmp(user, "__default__")) { + cil_printf("(selinuxuserdefault %s (", seuser); + } else { + cil_printf("(selinuxuser %s %s (", user, seuser); + } + + switch (matched) { + case 2: + cil_printf("systemlow systemlow"); + break; + case 3: + level_range_string_to_cil(level); + break; + } + + cil_printf("))\n"); + + free(user); + free(seuser); + free(level); + free(line); + user = seuser = level = NULL; + } + + if (rc == -1) { + cil_printf("Failed to read seusers\n"); + goto exit; + } + + rc = 0; +exit: + free(line); + free(user); + free(seuser); + free(level); + + return rc; +} + +static int netfilter_contexts_to_cil(struct sepol_module_package *mod_pkg) +{ + size_t netcons_len = sepol_module_package_get_netfilter_contexts_len(mod_pkg); + + if (netcons_len > 0) { + log_err("Warning: netfilter_contexts are unsupported in CIL. Dropping from output."); + } + + return 0; +} + +static int user_extra_to_cil(struct sepol_module_package *mod_pkg) +{ + int rc = -1; + char *userx = sepol_module_package_get_user_extra(mod_pkg); + size_t userx_len = sepol_module_package_get_user_extra_len(mod_pkg); + char *cur = userx; + char *end = userx + userx_len; + char *line; + int matched; + char *user = NULL; + char *prefix = NULL; + int prefix_len = 0; + char *user_str = NULL; + char *prefix_str = NULL; + char *eol = NULL; + char *tmp = NULL; + + if (userx_len == 0) { + return 0; + } + + while ((rc = get_line(&cur, end, &line)) > 0) { + tmp = line; + while (isspace(*tmp)) { + tmp++; + } + + if (tmp[0] == '#' || tmp[0] == '\0') { + free(line); + line = NULL; + continue; + } + + matched = tokenize(tmp, ' ', 4, &user_str, &user, &prefix_str, &prefix); + if (matched != 4) { + rc = -1; + log_err("Invalid user extra line: %s", line); + goto exit; + } + + prefix_len = strlen(prefix); + eol = prefix + prefix_len - 1; + if (*eol != ';' || strcmp(user_str, "user") || strcmp(prefix_str, "prefix")) { + rc = -1; + log_err("Invalid user extra line: %s", line); + goto exit; + } + *eol = '\0'; + + cil_println(0, "(userprefix %s %s)", user, prefix); + free(user); + free(prefix); + free(line); + free(user_str); + free(prefix_str); + user = prefix = line = user_str = prefix_str = NULL; + } + + if (rc == -1) { + cil_printf("Failed to read user_extra\n"); + goto exit; + } + + rc = 0; +exit: + free(line); + free(user); + free(prefix); + + return rc; +} + +static int file_contexts_to_cil(struct sepol_module_package *mod_pkg) +{ + int rc = -1; + char *fc = sepol_module_package_get_file_contexts(mod_pkg); + size_t fc_len = sepol_module_package_get_file_contexts_len(mod_pkg); + char *cur = fc; + char *end = fc + fc_len; + char *line = NULL; + int matched; + char *regex = NULL; + char *mode = NULL; + char *context = NULL; + const char *cilmode; + char *tmp = NULL; + + if (fc_len == 0) { + return 0; + } + + while ((rc = get_line(&cur, end, &line)) > 0) { + tmp = line; + while (isspace(*tmp)) { + tmp++; + } + + if (tmp[0] == '#' || tmp[0] == '\0') { + free(line); + line = NULL; + continue; + } + + matched = tokenize(tmp, ' ', 3, ®ex, &mode, &context); + if (matched < 2 || matched > 3) { + rc = -1; + log_err("Invalid file context line: %s", line); + goto exit; + } + + if (matched == 2) { + context = mode; + mode = NULL; + } + + if (mode == NULL) { + cilmode = "any"; + } else if (!strcmp(mode, "--")) { + cilmode = "file"; + } else if (!strcmp(mode, "-d")) { + cilmode = "dir"; + } else if (!strcmp(mode, "-c")) { + cilmode = "char"; + } else if (!strcmp(mode, "-b")) { + cilmode = "block"; + } else if (!strcmp(mode, "-s")) { + cilmode = "socket"; + } else if (!strcmp(mode, "-p")) { + cilmode = "pipe"; + } else if (!strcmp(mode, "-l")) { + cilmode = "symlink"; + } else { + rc = -1; + log_err("Invalid mode in file context line: %s", line); + goto exit; + } + + cil_printf("(filecon \"%s\" %s ", regex, cilmode); + + if (!strcmp(context, "<>")) { + cil_printf("()"); + } else { + context_string_to_cil(context); + } + + cil_printf(")\n"); + + free(regex); + free(mode); + free(context); + free(line); + regex = mode = context = line = NULL; + } + + if (rc == -1) { + cil_printf("Failed to read file_contexts_to_cil\n"); + goto exit; + } + + rc = 0; +exit: + free(line); + free(regex); + free(mode); + free(context); + + return rc; +} + + +static int (*func_to_cil[SYM_NUM])(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack, char *key, void *datum, int scope) = { + NULL, // commons, only stored in the global symtab, handled elsewhere + class_to_cil, + role_to_cil, + type_to_cil, + user_to_cil, + boolean_to_cil, + sens_to_cil, + cat_to_cil +}; + +static int typealiases_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack) +{ + struct type_datum *alias_datum; + char *alias_name; + char *type_name; + struct list_node *curr; + struct avrule_decl *decl = stack_peek(decl_stack); + struct list *alias_list; + int rc = -1; + + if (decl == NULL) { + return -1; + } + + alias_list = typealias_lists[decl->decl_id]; + if (alias_list == NULL) { + return 0; + } + + for (curr = alias_list->head; curr != NULL; curr = curr->next) { + alias_name = curr->data; + alias_datum = hashtab_search(pdb->p_types.table, alias_name); + if (alias_datum == NULL) { + rc = -1; + goto exit; + } + if (alias_datum->flavor == TYPE_ALIAS) { + type_name = pdb->p_type_val_to_name[alias_datum->primary - 1]; + } else { + type_name = pdb->p_type_val_to_name[alias_datum->s.value - 1]; + } + cil_println(indent, "(typealias %s)", alias_name); + cil_println(indent, "(typealiasactual %s %s)", alias_name, type_name); + } + + return 0; + +exit: + return rc; +} + +static int declared_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack) +{ + int rc = -1; + struct ebitmap map; + struct ebitmap_node *node; + unsigned int i; + char * key; + struct scope_datum *scope; + int sym; + void *datum; + struct avrule_decl *decl = stack_peek(decl_stack); + + for (sym = 0; sym < SYM_NUM; sym++) { + if (func_to_cil[sym] == NULL) { + continue; + } + + map = decl->declared.scope[sym]; + ebitmap_for_each_positive_bit(&map, node, i) { + key = pdb->sym_val_to_name[sym][i]; + datum = hashtab_search(pdb->symtab[sym].table, key); + if (datum == NULL) { + rc = -1; + goto exit; + } + scope = hashtab_search(pdb->scope[sym].table, key); + if (scope == NULL) { + rc = -1; + goto exit; + } + rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, scope->scope); + if (rc != 0) { + goto exit; + } + } + + if (sym == SYM_CATS) { + rc = cat_order_to_cil(indent, pdb, map); + if (rc != 0) { + goto exit; + } + } + + if (sym == SYM_LEVELS) { + rc = sens_order_to_cil(indent, pdb, map); + if (rc != 0) { + goto exit; + } + } + + if (sym == SYM_CLASSES) { + rc = class_order_to_cil(indent, pdb, map); + if (rc != 0) { + goto exit; + } + } + } + + return 0; +exit: + return rc; +} + +static int required_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack) +{ + int rc = -1; + struct ebitmap map; + struct ebitmap_node *node; + unsigned int i; + unsigned int j; + char * key; + int sym; + void *datum; + struct avrule_decl *decl = stack_peek(decl_stack); + struct scope_datum *scope_datum; + + for (sym = 0; sym < SYM_NUM; sym++) { + if (func_to_cil[sym] == NULL) { + continue; + } + + map = decl->required.scope[sym]; + ebitmap_for_each_positive_bit(&map, node, i) { + key = pdb->sym_val_to_name[sym][i]; + + scope_datum = hashtab_search(pdb->scope[sym].table, key); + if (scope_datum == NULL) { + rc = -1; + goto exit; + } + for (j = 0; j < scope_datum->decl_ids_len; j++) { + if (scope_datum->decl_ids[j] == decl->decl_id) { + break; + } + } + if (j >= scope_datum->decl_ids_len) { + // Symbols required in the global scope are also in the + // required scope ebitmap of all avrule decls (i.e. required + // in all optionals). So we need to look at the scopes of each + // symbol in this avrule_decl to determine if it actually is + // required in this decl, or if it's just required in the + // global scope. If we got here, then this symbol is not + // actually required in this scope, so skip it. + continue; + } + + datum = hashtab_search(pdb->symtab[sym].table, key); + if (datum == NULL) { + rc = -1; + goto exit; + } + rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, SCOPE_REQ); + if (rc != 0) { + goto exit; + } + } + } + + return 0; +exit: + return rc; +} + + +static int additive_scopes_to_cil_map(char *key, void *data, void *arg) +{ + int rc = -1; + struct map_args *args = arg; + + rc = func_to_cil[args->sym_index](args->indent, args->pdb, args->block, args->decl_stack, key, data, SCOPE_REQ); + if (rc != 0) { + goto exit; + } + + return 0; + +exit: + return rc; +} + +static int additive_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack) +{ + int rc = -1; + struct avrule_decl *decl = stack_peek(decl_stack); + struct map_args args; + args.pdb = pdb; + args.block = block; + args.decl_stack = decl_stack; + args.indent = indent; + + for (args.sym_index = 0; args.sym_index < SYM_NUM; args.sym_index++) { + if (func_to_cil[args.sym_index] == NULL) { + continue; + } + rc = ksu_hashtab_map(decl->symtab[args.sym_index].table, additive_scopes_to_cil_map, &args); + if (rc != 0) { + goto exit; + } + } + + return 0; + +exit: + return rc; +} + +static int is_scope_superset(struct scope_index *sup, struct scope_index *sub) +{ + // returns 1 if sup is a superset of sub, returns 0 otherwise + + int rc = 0; + + uint32_t i; + struct ebitmap sup_map; + struct ebitmap sub_map; + struct ebitmap res; + + ebitmap_init(&res); + + for (i = 0; i < SYM_NUM; i++) { + sup_map = sup->scope[i]; + sub_map = sub->scope[i]; + + ksu_ebitmap_and(&res, &sup_map, &sub_map); + if (!ksu_ebitmap_cmp(&res, &sub_map)) { + goto exit; + } + ksu_ebitmap_destroy(&res); + } + + if (sup->class_perms_len < sub->class_perms_len) { + goto exit; + } + + for (i = 0; i < sub->class_perms_len; i++) { + sup_map = sup->class_perms_map[i]; + sub_map = sub->class_perms_map[i]; + + ksu_ebitmap_and(&res, &sup_map, &sub_map); + if (!ksu_ebitmap_cmp(&res, &sub_map)) { + goto exit; + } + ksu_ebitmap_destroy(&res); + } + + rc = 1; + +exit: + + ksu_ebitmap_destroy(&res); + return rc; +} + +static int block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int indent) +{ + int rc = -1; + struct avrule_decl *decl; + struct list *type_attr_list = NULL; + struct list *role_attr_list = NULL; + + decl = block->branch_list; + + rc = list_init(&type_attr_list); + if (rc != 0) { + goto exit; + } + rc = list_init(&role_attr_list); + if (rc != 0) { + goto exit; + } + + rc = typealiases_to_cil(indent, pdb, block, stack); + if (rc != 0) { + goto exit; + } + + rc = declared_scopes_to_cil(indent, pdb, block, stack); + if (rc != 0) { + goto exit; + } + + rc = required_scopes_to_cil(indent, pdb, block, stack); + if (rc != 0) { + goto exit; + } + + rc = additive_scopes_to_cil(indent, pdb, block, stack); + if (rc != 0) { + goto exit; + } + + rc = avrule_list_to_cil(indent, pdb, decl->avrules, type_attr_list); + if (rc != 0) { + goto exit; + } + + rc = role_trans_to_cil(indent, pdb, decl->role_tr_rules, role_attr_list, type_attr_list); + if (rc != 0) { + goto exit; + } + + rc = role_allows_to_cil(indent, pdb, decl->role_allow_rules, role_attr_list); + if (rc != 0) { + goto exit; + } + + rc = range_trans_to_cil(indent, pdb, decl->range_tr_rules, type_attr_list); + if (rc != 0) { + goto exit; + } + + rc = filename_trans_to_cil(indent, pdb, decl->filename_trans_rules, type_attr_list); + if (rc != 0) { + goto exit; + } + + rc = cond_list_to_cil(indent, pdb, decl->cond_list, type_attr_list); + if (rc != 0) { + goto exit; + } + + rc = cil_print_attr_list(indent, pdb, type_attr_list); + if (rc != 0) { + goto exit; + } + rc = cil_print_attr_list(indent, pdb, role_attr_list); + if (rc != 0) { + goto exit; + } + +exit: + attr_list_destroy(&type_attr_list); + attr_list_destroy(&role_attr_list); + + return rc; +} + +static int module_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int *indent) +{ + int rc = 0; + struct avrule_decl *decl; + struct avrule_decl *decl_tmp; + + decl = block->branch_list; + if (decl == NULL) { + goto exit; + } + + if (decl->next != NULL) { + log_err("Warning: 'else' blocks in optional statements are unsupported in CIL. Dropping from output."); + } + + if (block->flags & AVRULE_OPTIONAL) { + while (stack->pos > 0) { + decl_tmp = stack_peek(stack); + if (is_scope_superset(&decl->required, &decl_tmp->required)) { + break; + } + + stack_pop(stack); + (*indent)--; + cil_println(*indent, ")"); + } + + cil_println(*indent, "(optional %s_optional_%i", pdb->name, decl->decl_id); + (*indent)++; + } + + stack_push(stack, decl); + + rc = block_to_cil(pdb, block, stack, *indent); + if (rc != 0) { + goto exit; + } + +exit: + return rc; +} + +static int global_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack) +{ + int rc = 0; + struct avrule_decl *decl; + + decl = block->branch_list; + if (decl == NULL) { + goto exit; + } + + if (decl->next != NULL) { + log_err("Warning: 'else' not allowed in global block. Dropping from output."); + } + + stack_push(stack, decl); + + // type aliases and commons are only stored in the global symtab. + // However, to get scoping correct, we assume they are in the + // global block + rc = ksu_hashtab_map(pdb->p_commons.table, common_to_cil, NULL); + if (rc != 0) { + goto exit; + } + + rc = block_to_cil(pdb, block, stack, 0); + if (rc != 0) { + goto exit; + } + +exit: + return rc; +} + +static int blocks_to_cil(struct policydb *pdb) +{ + int rc = -1; + struct avrule_block *block; + int indent = 0; + struct stack *stack = NULL; + + rc = stack_init(&stack); + if (rc != 0) { + goto exit; + } + + block = pdb->global; + rc = global_block_to_cil(pdb, block, stack); + if (rc != 0) { + goto exit; + } + + for (block = block->next; block != NULL; block = block->next) { + rc = module_block_to_cil(pdb, block, stack, &indent); + if (rc != 0) { + goto exit; + } + } + + while (indent > 0) { + indent--; + cil_println(indent, ")"); + } + +exit: + stack_destroy(&stack); + + return rc; +} + +static int linked_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack) +{ + int rc = 0; + struct avrule_decl *decl; + + decl = block->branch_list; + if (decl == NULL) { + goto exit; + } + + if (!decl->enabled) { + if (decl->next != NULL) { + decl = decl->next; + } else { + goto exit; + } + } + + stack_push(stack, decl); + + rc = block_to_cil(pdb, block, stack, 0); + if (rc != 0) { + goto exit; + } + + stack_pop(stack); + +exit: + return rc; +} + +static int linked_blocks_to_cil(struct policydb *pdb) +{ + // Convert base module that has been linked to CIL + // Since it is linked, all optional blocks have been resolved + int rc = -1; + struct avrule_block *block; + struct stack *stack = NULL; + + rc = stack_init(&stack); + if (rc != 0) { + goto exit; + } + + block = pdb->global; + rc = global_block_to_cil(pdb, block, stack); + if (rc != 0) { + goto exit; + } + + for (block = block->next; block != NULL; block = block->next) { + rc = linked_block_to_cil(pdb, block, stack); + if (rc != 0) { + goto exit; + } + } + +exit: + stack_destroy(&stack); + + return rc; +} + +static int handle_unknown_to_cil(struct policydb *pdb) +{ + int rc = -1; + const char *hu; + + switch (pdb->handle_unknown) { + case SEPOL_DENY_UNKNOWN: + hu = "deny"; + break; + case SEPOL_REJECT_UNKNOWN: + hu = "reject"; + break; + case SEPOL_ALLOW_UNKNOWN: + hu = "allow"; + break; + default: + log_err("Unknown value for handle-unknown: %i", pdb->handle_unknown); + rc = -1; + goto exit; + } + + cil_println(0, "(handleunknown %s)", hu); + + return 0; + +exit: + return rc; +} + +static int generate_mls(struct policydb *pdb) +{ + const char *mls_str = pdb->mls ? "true" : "false"; + cil_println(0, "(mls %s)", mls_str); + + return 0; +} + +static int generate_default_level(void) +{ + cil_println(0, "(sensitivity s0)"); + cil_println(0, "(sensitivityorder (s0))"); + cil_println(0, "(level " DEFAULT_LEVEL " (s0))"); + + return 0; +} + +static int generate_default_object(void) +{ + cil_println(0, "(role " DEFAULT_OBJECT ")"); + + return 0; +} + +static int generate_builtin_roles(void) +{ + // due to inconsistentencies between policies and CIL not allowing + // duplicate roles, some roles are always created, regardless of if they + // are declared in modules or not + cil_println(0, "(role auditadm_r)"); + cil_println(0, "(role secadm_r)"); + + return 0; +} + +static int generate_gen_require_attribute(void) +{ + cil_println(0, "(typeattribute " GEN_REQUIRE_ATTR ")"); + cil_println(0, "(roleattribute " GEN_REQUIRE_ATTR ")"); + + return 0; +} + +static int fix_module_name(struct policydb *pdb) +{ + char *letter; + int rc = -1; + + // The base module doesn't have its name set, but we use that for some + // autogenerated names, like optionals and attributes, to prevent naming + // collisions. However, they sometimes need to be fixed up. + + // the base module isn't given a name, so just call it "base" + if (pdb->policy_type == POLICY_BASE) { + pdb->name = strdup("base"); + if (pdb->name == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + } + + // CIL is more restrictive in module names than checkmodule. Convert bad + // characters to underscores + for (letter = pdb->name; *letter != '\0'; letter++) { + if (isalnum(*letter)) { + continue; + } + + *letter = '_'; + } + + return 0; +exit: + return rc; +} + +int sepol_module_policydb_to_cil(FILE *fp, struct policydb *pdb, int linked) +{ + int rc = -1; + + out_file = fp; + + if (pdb == NULL) { + rc = 0; + goto exit; + } + + if (pdb->policy_type != SEPOL_POLICY_BASE && + pdb->policy_type != SEPOL_POLICY_MOD) { + log_err("Policy package is not a base or module"); + rc = -1; + goto exit; + } + + rc = fix_module_name(pdb); + if (rc != 0) { + goto exit; + } + + if (pdb->policy_type == SEPOL_POLICY_BASE && !pdb->mls) { + // If this is a base non-mls policy, we need to define a default level + // range that can be used for contexts by other non-mls modules, since + // CIL requires that all contexts have a range, even if they are + // ignored as in non-mls policies + rc = generate_default_level(); + if (rc != 0) { + goto exit; + } + } + + if (pdb->policy_type == SEPOL_POLICY_BASE) { + // object_r is implicit in checkmodule, but not with CIL, create it + // as part of base + rc = generate_default_object(); + if (rc != 0) { + goto exit; + } + + rc = generate_builtin_roles(); + if (rc != 0) { + goto exit; + } + + // default attribute to be used to mimic gen_require in CIL + rc = generate_gen_require_attribute(); + if (rc != 0) { + goto exit; + } + + // handle_unknown is used from only the base module + rc = handle_unknown_to_cil(pdb); + if (rc != 0) { + goto exit; + } + + // mls is used from only the base module + rc = generate_mls(pdb); + if (rc != 0) { + goto exit; + } + } + + rc = role_list_create(pdb->p_roles.table); + if (rc != 0) { + goto exit; + } + + rc = typealias_list_create(pdb); + if (rc != 0) { + goto exit; + } + + rc = polcaps_to_cil(pdb); + if (rc != 0) { + goto exit; + } + + rc = ocontexts_to_cil(pdb); + if (rc != 0) { + goto exit; + } + + rc = genfscon_to_cil(pdb); + if (rc != 0) { + goto exit; + } + + // now print everything that is scoped + if (linked) { + rc = linked_blocks_to_cil(pdb); + } else { + rc = blocks_to_cil(pdb); + } + if (rc != 0) { + goto exit; + } + + rc = 0; + +exit: + role_list_destroy(); + typealias_list_destroy(); + + return rc; +} + +int sepol_module_package_to_cil(FILE *fp, struct sepol_module_package *mod_pkg) +{ + int rc = -1; + struct sepol_policydb *pdb; + + out_file = fp; + + pdb = sepol_module_package_get_policy(mod_pkg); + if (pdb == NULL) { + log_err("Failed to get policydb"); + rc = -1; + goto exit; + } + + rc = sepol_module_policydb_to_cil(fp, &pdb->p, 0); + if (rc != 0) { + goto exit; + } + + rc = seusers_to_cil(mod_pkg); + if (rc != 0) { + goto exit; + } + + rc = netfilter_contexts_to_cil(mod_pkg); + if (rc != 0) { + goto exit; + } + + rc = user_extra_to_cil(mod_pkg); + if (rc != 0) { + goto exit; + } + + rc = file_contexts_to_cil(mod_pkg); + if (rc != 0) { + goto exit; + } + + rc = 0; + +exit: + return rc; +} + +static int fp_to_buffer(FILE *fp, char **data, size_t *data_len) +{ + int rc = -1; + char *d = NULL, *d_tmp; + size_t d_len = 0; + size_t read_len = 0; + size_t max_len = 1 << 17; // start at 128KB, this is enough to hold about half of all the existing pp files + + d = malloc(max_len); + if (d == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + + while ((read_len = fread(d + d_len, 1, max_len - d_len, fp)) > 0) { + d_len += read_len; + if (d_len == max_len) { + max_len *= 2; + d_tmp = realloc(d, max_len); + if (d_tmp == NULL) { + log_err("Out of memory"); + rc = -1; + goto exit; + } + d = d_tmp; + } + } + + if (ferror(fp) != 0) { + log_err("Failed to read pp file"); + rc = -1; + goto exit; + } + + *data = d; + *data_len = d_len; + + return 0; + +exit: + free(d); + return rc; +} + +int sepol_ppfile_to_module_package(FILE *fp, struct sepol_module_package **mod_pkg) +{ + int rc = -1; + struct sepol_policy_file *pf = NULL; + struct sepol_module_package *pkg = NULL; + char *data = NULL; + size_t data_len; + int fd; + struct stat sb; + + rc = sepol_policy_file_create(&pf); + if (rc != 0) { + log_err("Failed to create policy file"); + goto exit; + } + + fd = fileno(fp); + if (fstat(fd, &sb) == -1) { + rc = -1; + goto exit; + } + + if (S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode)) { + // libsepol fails when trying to read a policy package from a pipe or a + // socket due its use of lseek. In this case, read the data into a + // buffer and provide that to libsepol + rc = fp_to_buffer(fp, &data, &data_len); + if (rc != 0) { + goto exit; + } + + sepol_policy_file_set_mem(pf, data, data_len); + } else { + sepol_policy_file_set_fp(pf, fp); + } + + rc = sepol_module_package_create(&pkg); + if (rc != 0) { + log_err("Failed to create module package"); + goto exit; + } + + rc = sepol_module_package_read(pkg, pf, 0); + if (rc != 0) { + log_err("Failed to read policy package"); + goto exit; + } + + *mod_pkg = pkg; + +exit: + free(data); + + sepol_policy_file_free(pf); + + if (rc != 0) { + sepol_module_package_free(pkg); + } + + return rc; +} diff --git a/kernel/libsepol/src/node_internal.h b/kernel/libsepol/src/node_internal.h new file mode 100644 index 00000000..6d3c2505 --- /dev/null +++ b/kernel/libsepol/src/node_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_NODE_INTERNAL_H_ +#define _SEPOL_NODE_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/node_record.c b/kernel/libsepol/src/node_record.c new file mode 100644 index 00000000..65575388 --- /dev/null +++ b/kernel/libsepol/src/node_record.c @@ -0,0 +1,649 @@ +// #include +// #include +#include +// #include +#include +// #include +#include +// #include + +#include "node_internal.h" +#include "context_internal.h" +#include "debug.h" + +struct sepol_node { + + /* Network address and mask */ + char *addr; + size_t addr_sz; + + char *mask; + size_t mask_sz; + + /* Protocol */ + int proto; + + /* Context */ + sepol_context_t *con; +}; + +struct sepol_node_key { + + /* Network address and mask */ + char *addr; + size_t addr_sz; + + char *mask; + size_t mask_sz; + + /* Protocol */ + int proto; +}; + +/* Converts a string represtation (addr_str) + * to a numeric representation (addr_bytes) */ + +static int node_parse_addr(sepol_handle_t * handle, + const char *addr_str, int proto, char *addr_bytes) +{ + + switch (proto) { + + case SEPOL_PROTO_IP4: + { + struct in_addr in_addr; + + if (inet_pton(AF_INET, addr_str, &in_addr) <= 0) { + ERR(handle, "could not parse IPv4 address " + "%s: %m", addr_str); + return STATUS_ERR; + } + + memcpy(addr_bytes, &in_addr.s_addr, 4); + break; + } + case SEPOL_PROTO_IP6: + { + struct in6_addr in_addr; + + if (inet_pton(AF_INET6, addr_str, &in_addr) <= 0) { + ERR(handle, "could not parse IPv6 address " + "%s: %m", addr_str); + return STATUS_ERR; + } + + memcpy(addr_bytes, in_addr.s6_addr, 16); + break; + } + default: + ERR(handle, "unsupported protocol %u, could not " + "parse address", proto); + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +/* Allocates a sufficiently large buffer (addr, addr_sz) + * according to the protocol */ + +static int node_alloc_addr(sepol_handle_t * handle, + int proto, char **addr, size_t * addr_sz) +{ + + char *tmp_addr = NULL; + size_t tmp_addr_sz; + + switch (proto) { + + case SEPOL_PROTO_IP4: + tmp_addr_sz = 4; + tmp_addr = malloc(4); + if (!tmp_addr) + goto omem; + break; + + case SEPOL_PROTO_IP6: + tmp_addr_sz = 16; + tmp_addr = malloc(16); + if (!tmp_addr) + goto omem; + break; + + default: + ERR(handle, "unsupported protocol %u", proto); + goto err; + } + + *addr = tmp_addr; + *addr_sz = tmp_addr_sz; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + free(tmp_addr); + ERR(handle, "could not allocate address of protocol %s", + sepol_node_get_proto_str(proto)); + return STATUS_ERR; +} + +/* Converts a numeric representation (addr_bytes) + * to a string representation (addr_str), according to + * the protocol */ + +static int node_expand_addr(sepol_handle_t * handle, + char *addr_bytes, int proto, char *addr_str) +{ + + switch (proto) { + + case SEPOL_PROTO_IP4: + { + struct in_addr addr; + memset(&addr, 0, sizeof(struct in_addr)); + memcpy(&addr.s_addr, addr_bytes, 4); + + if (inet_ntop(AF_INET, &addr, addr_str, + INET_ADDRSTRLEN) == NULL) { + + ERR(handle, + "could not expand IPv4 address to string: %m"); + return STATUS_ERR; + } + break; + } + + case SEPOL_PROTO_IP6: + { + struct in6_addr addr; + memset(&addr, 0, sizeof(struct in6_addr)); + memcpy(&addr.s6_addr[0], addr_bytes, 16); + if (inet_ntop(AF_INET6, &addr, addr_str, + INET6_ADDRSTRLEN) == NULL) { + + ERR(handle, + "could not expand IPv6 address to string: %m"); + return STATUS_ERR; + } + break; + } + + default: + ERR(handle, "unsupported protocol %u, could not" + " expand address to string", proto); + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +/* Allocates a sufficiently large address string (addr) + * according to the protocol */ + +static int node_alloc_addr_string(sepol_handle_t * handle, + int proto, char **addr) +{ + + char *tmp_addr = NULL; + + switch (proto) { + + case SEPOL_PROTO_IP4: + tmp_addr = malloc(INET_ADDRSTRLEN); + if (!tmp_addr) + goto omem; + break; + + case SEPOL_PROTO_IP6: + tmp_addr = malloc(INET6_ADDRSTRLEN); + if (!tmp_addr) + goto omem; + break; + + default: + ERR(handle, "unsupported protocol %u", proto); + goto err; + } + + *addr = tmp_addr; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + free(tmp_addr); + ERR(handle, "could not allocate string buffer for " + "address of protocol %s", sepol_node_get_proto_str(proto)); + return STATUS_ERR; +} + +/* Key */ +int sepol_node_key_create(sepol_handle_t * handle, + const char *addr, + const char *mask, + int proto, sepol_node_key_t ** key_ptr) +{ + + sepol_node_key_t *tmp_key = + (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t)); + if (!tmp_key) + goto omem; + + if (node_alloc_addr(handle, proto, &tmp_key->addr, &tmp_key->addr_sz) < + 0) + goto err; + if (node_parse_addr(handle, addr, proto, tmp_key->addr) < 0) + goto err; + + if (node_alloc_addr(handle, proto, &tmp_key->mask, &tmp_key->mask_sz) < + 0) + goto err; + if (node_parse_addr(handle, mask, proto, tmp_key->mask) < 0) + goto err; + + tmp_key->proto = proto; + + *key_ptr = tmp_key; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + sepol_node_key_free(tmp_key); + ERR(handle, "could not create node key for (%s, %s, %s)", + addr, mask, sepol_node_get_proto_str(proto)); + return STATUS_ERR; +} + + +void sepol_node_key_unpack(const sepol_node_key_t * key, + const char **addr, const char **mask, int *proto) +{ + + *addr = key->addr; + *mask = key->mask; + *proto = key->proto; +} + + +int sepol_node_key_extract(sepol_handle_t * handle, + const sepol_node_t * node, + sepol_node_key_t ** key_ptr) +{ + + sepol_node_key_t *tmp_key = + (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t)); + if (!tmp_key) + goto omem; + + tmp_key->addr = malloc(node->addr_sz); + tmp_key->mask = malloc(node->mask_sz); + + if (!tmp_key->addr || !tmp_key->mask) + goto omem; + + memcpy(tmp_key->addr, node->addr, node->addr_sz); + memcpy(tmp_key->mask, node->mask, node->mask_sz); + tmp_key->addr_sz = node->addr_sz; + tmp_key->mask_sz = node->mask_sz; + tmp_key->proto = node->proto; + + *key_ptr = tmp_key; + return STATUS_SUCCESS; + + omem: + sepol_node_key_free(tmp_key); + ERR(handle, "out of memory, could not extract node key"); + return STATUS_ERR; +} + +void sepol_node_key_free(sepol_node_key_t * key) +{ + + if (!key) + return; + + free(key->addr); + free(key->mask); + free(key); +} + + +int sepol_node_compare(const sepol_node_t * node, const sepol_node_key_t * key) +{ + + int rc1, rc2; + + if ((node->addr_sz < key->addr_sz) || (node->mask_sz < key->mask_sz)) + return -1; + + else if ((node->addr_sz > key->addr_sz) || + (node->mask_sz > key->mask_sz)) + return 1; + + rc1 = memcmp(node->addr, key->addr, node->addr_sz); + rc2 = memcmp(node->mask, key->mask, node->mask_sz); + + return (rc2 != 0) ? rc2 : rc1; +} + +int sepol_node_compare2(const sepol_node_t * node, const sepol_node_t * node2) +{ + + int rc1, rc2; + + if ((node->addr_sz < node2->addr_sz) || + (node->mask_sz < node2->mask_sz)) + return -1; + + else if ((node->addr_sz > node2->addr_sz) || + (node->mask_sz > node2->mask_sz)) + return 1; + + rc1 = memcmp(node->addr, node2->addr, node->addr_sz); + rc2 = memcmp(node->mask, node2->mask, node->mask_sz); + + return (rc2 != 0) ? rc2 : rc1; +} + +/* Addr */ +int sepol_node_get_addr(sepol_handle_t * handle, + const sepol_node_t * node, char **addr) +{ + + char *tmp_addr = NULL; + + if (node_alloc_addr_string(handle, node->proto, &tmp_addr) < 0) + goto err; + + if (node_expand_addr(handle, node->addr, node->proto, tmp_addr) < 0) + goto err; + + *addr = tmp_addr; + return STATUS_SUCCESS; + + err: + free(tmp_addr); + ERR(handle, "could not get node address"); + return STATUS_ERR; +} + + +int sepol_node_get_addr_bytes(sepol_handle_t * handle, + const sepol_node_t * node, + char **buffer, size_t * bsize) +{ + + char *tmp_buf = malloc(node->addr_sz); + if (!tmp_buf) { + ERR(handle, "out of memory, could not get address bytes"); + return STATUS_ERR; + } + + memcpy(tmp_buf, node->addr, node->addr_sz); + *buffer = tmp_buf; + *bsize = node->addr_sz; + return STATUS_SUCCESS; +} + + +int sepol_node_set_addr(sepol_handle_t * handle, + sepol_node_t * node, int proto, const char *addr) +{ + + char *tmp_addr = NULL; + size_t tmp_addr_sz; + + if (node_alloc_addr(handle, proto, &tmp_addr, &tmp_addr_sz) < 0) + goto err; + + if (node_parse_addr(handle, addr, proto, tmp_addr) < 0) + goto err; + + free(node->addr); + node->addr = tmp_addr; + node->addr_sz = tmp_addr_sz; + return STATUS_SUCCESS; + + err: + free(tmp_addr); + ERR(handle, "could not set node address to %s", addr); + return STATUS_ERR; +} + + +int sepol_node_set_addr_bytes(sepol_handle_t * handle, + sepol_node_t * node, + const char *addr, size_t addr_sz) +{ + + char *tmp_addr = malloc(addr_sz); + if (!tmp_addr) { + ERR(handle, "out of memory, could not " "set node address"); + return STATUS_ERR; + } + + memcpy(tmp_addr, addr, addr_sz); + free(node->addr); + node->addr = tmp_addr; + node->addr_sz = addr_sz; + return STATUS_SUCCESS; +} + + +/* Mask */ +int sepol_node_get_mask(sepol_handle_t * handle, + const sepol_node_t * node, char **mask) +{ + + char *tmp_mask = NULL; + + if (node_alloc_addr_string(handle, node->proto, &tmp_mask) < 0) + goto err; + + if (node_expand_addr(handle, node->mask, node->proto, tmp_mask) < 0) + goto err; + + *mask = tmp_mask; + return STATUS_SUCCESS; + + err: + free(tmp_mask); + ERR(handle, "could not get node netmask"); + return STATUS_ERR; +} + + +int sepol_node_get_mask_bytes(sepol_handle_t * handle, + const sepol_node_t * node, + char **buffer, size_t * bsize) +{ + + char *tmp_buf = malloc(node->mask_sz); + if (!tmp_buf) { + ERR(handle, "out of memory, could not get netmask bytes"); + return STATUS_ERR; + } + + memcpy(tmp_buf, node->mask, node->mask_sz); + *buffer = tmp_buf; + *bsize = node->mask_sz; + return STATUS_SUCCESS; +} + + +int sepol_node_set_mask(sepol_handle_t * handle, + sepol_node_t * node, int proto, const char *mask) +{ + + char *tmp_mask = NULL; + size_t tmp_mask_sz; + + if (node_alloc_addr(handle, proto, &tmp_mask, &tmp_mask_sz) < 0) + goto err; + + if (node_parse_addr(handle, mask, proto, tmp_mask) < 0) + goto err; + + free(node->mask); + node->mask = tmp_mask; + node->mask_sz = tmp_mask_sz; + return STATUS_SUCCESS; + + err: + free(tmp_mask); + ERR(handle, "could not set node netmask to %s", mask); + return STATUS_ERR; +} + + +int sepol_node_set_mask_bytes(sepol_handle_t * handle, + sepol_node_t * node, + const char *mask, size_t mask_sz) +{ + + char *tmp_mask = malloc(mask_sz); + if (!tmp_mask) { + ERR(handle, "out of memory, could not " "set node netmask"); + return STATUS_ERR; + } + memcpy(tmp_mask, mask, mask_sz); + free(node->mask); + node->mask = tmp_mask; + node->mask_sz = mask_sz; + return STATUS_SUCCESS; +} + + +/* Protocol */ +int sepol_node_get_proto(const sepol_node_t * node) +{ + + return node->proto; +} + + +void sepol_node_set_proto(sepol_node_t * node, int proto) +{ + + node->proto = proto; +} + + +const char *sepol_node_get_proto_str(int proto) +{ + + switch (proto) { + case SEPOL_PROTO_IP4: + return "ipv4"; + case SEPOL_PROTO_IP6: + return "ipv6"; + default: + return "???"; + } +} + + +/* Create */ +int sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node) +{ + + sepol_node_t *tmp_node = (sepol_node_t *) malloc(sizeof(sepol_node_t)); + + if (!tmp_node) { + ERR(handle, "out of memory, could not create " "node record"); + return STATUS_ERR; + } + + tmp_node->addr = NULL; + tmp_node->addr_sz = 0; + tmp_node->mask = NULL; + tmp_node->mask_sz = 0; + tmp_node->proto = SEPOL_PROTO_IP4; + tmp_node->con = NULL; + *node = tmp_node; + + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_node_clone(sepol_handle_t * handle, + const sepol_node_t * node, sepol_node_t ** node_ptr) +{ + + sepol_node_t *new_node = NULL; + if (sepol_node_create(handle, &new_node) < 0) + goto err; + + /* Copy address, mask, protocol */ + new_node->addr = malloc(node->addr_sz); + new_node->mask = malloc(node->mask_sz); + if (!new_node->addr || !new_node->mask) + goto omem; + + memcpy(new_node->addr, node->addr, node->addr_sz); + memcpy(new_node->mask, node->mask, node->mask_sz); + new_node->addr_sz = node->addr_sz; + new_node->mask_sz = node->mask_sz; + new_node->proto = node->proto; + + /* Copy context */ + if (node->con && + (sepol_context_clone(handle, node->con, &new_node->con) < 0)) + goto err; + + *node_ptr = new_node; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + ERR(handle, "could not clone node record"); + sepol_node_free(new_node); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_node_free(sepol_node_t * node) +{ + + if (!node) + return; + + sepol_context_free(node->con); + free(node->addr); + free(node->mask); + free(node); +} + + +/* Context */ +sepol_context_t *sepol_node_get_con(const sepol_node_t * node) +{ + + return node->con; +} + + +int sepol_node_set_con(sepol_handle_t * handle, + sepol_node_t * node, sepol_context_t * con) +{ + + sepol_context_t *newcon; + + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set node context"); + return STATUS_ERR; + } + + sepol_context_free(node->con); + node->con = newcon; + return STATUS_SUCCESS; +} + diff --git a/kernel/libsepol/src/node_record.o b/kernel/libsepol/src/node_record.o new file mode 100644 index 00000000..4f36f0dc Binary files /dev/null and b/kernel/libsepol/src/node_record.o differ diff --git a/kernel/libsepol/src/nodes.c b/kernel/libsepol/src/nodes.c new file mode 100644 index 00000000..225efb3d --- /dev/null +++ b/kernel/libsepol/src/nodes.c @@ -0,0 +1,402 @@ +// #include +#include +// #include +#include +// #include + +#include "debug.h" +#include "context.h" +#include "handle.h" + +#include +#include "node_internal.h" + +/* Create a low level node structure from + * a high level representation */ +static int node_from_record(sepol_handle_t * handle, + const policydb_t * policydb, + ocontext_t ** node, const sepol_node_t * data) +{ + + ocontext_t *tmp_node = NULL; + context_struct_t *tmp_con = NULL; + char *addr_buf = NULL, *mask_buf = NULL; + size_t addr_bsize, mask_bsize; + int proto; + + tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t)); + if (!tmp_node) + goto omem; + + /* Address and netmask */ + if (sepol_node_get_addr_bytes(handle, data, &addr_buf, &addr_bsize) < 0) + goto err; + if (sepol_node_get_mask_bytes(handle, data, &mask_buf, &mask_bsize) < 0) + goto err; + + proto = sepol_node_get_proto(data); + + switch (proto) { + case SEPOL_PROTO_IP4: + memcpy(&tmp_node->u.node.addr, addr_buf, addr_bsize); + memcpy(&tmp_node->u.node.mask, mask_buf, mask_bsize); + break; + case SEPOL_PROTO_IP6: + memcpy(tmp_node->u.node6.addr, addr_buf, addr_bsize); + memcpy(tmp_node->u.node6.mask, mask_buf, mask_bsize); + break; + default: + ERR(handle, "unsupported protocol %u", proto); + goto err; + } + free(addr_buf); + free(mask_buf); + addr_buf = NULL; + mask_buf = NULL; + + /* Context */ + if (context_from_record(handle, policydb, &tmp_con, + sepol_node_get_con(data)) < 0) + goto err; + context_cpy(&tmp_node->context[0], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + *node = tmp_node; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + if (tmp_node != NULL) { + context_destroy(&tmp_node->context[0]); + free(tmp_node); + } + context_destroy(tmp_con); + free(tmp_con); + free(addr_buf); + free(mask_buf); + ERR(handle, "could not create node structure"); + return STATUS_ERR; +} + +static int node_to_record(sepol_handle_t * handle, + const policydb_t * policydb, + ocontext_t * node, int proto, sepol_node_t ** record) +{ + + context_struct_t *con = &node->context[0]; + + sepol_context_t *tmp_con = NULL; + sepol_node_t *tmp_record = NULL; + + if (sepol_node_create(handle, &tmp_record) < 0) + goto err; + + sepol_node_set_proto(tmp_record, proto); + + switch (proto) { + + case SEPOL_PROTO_IP4: + if (sepol_node_set_addr_bytes(handle, tmp_record, + (const char *)&node->u.node.addr, + 4) < 0) + goto err; + + if (sepol_node_set_mask_bytes(handle, tmp_record, + (const char *)&node->u.node.mask, + 4) < 0) + goto err; + break; + + case SEPOL_PROTO_IP6: + if (sepol_node_set_addr_bytes(handle, tmp_record, + (const char *)&node->u.node6.addr, + 16) < 0) + goto err; + + if (sepol_node_set_mask_bytes(handle, tmp_record, + (const char *)&node->u.node6.mask, + 16) < 0) + goto err; + break; + + default: + ERR(handle, "unsupported protocol %u", proto); + goto err; + } + + if (context_to_record(handle, policydb, con, &tmp_con) < 0) + goto err; + + if (sepol_node_set_con(handle, tmp_record, tmp_con) < 0) + goto err; + + sepol_context_free(tmp_con); + *record = tmp_record; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not convert node to record"); + sepol_context_free(tmp_con); + sepol_node_free(tmp_record); + return STATUS_ERR; +} + +/* Return the number of nodes */ +extern int sepol_node_count(sepol_handle_t * handle __attribute__ ((unused)), + const sepol_policydb_t * p, unsigned int *response) +{ + + unsigned int count = 0; + ocontext_t *c, *head; + const policydb_t *policydb = &p->p; + + head = policydb->ocontexts[OCON_NODE]; + for (c = head; c != NULL; c = c->next) + count++; + + head = policydb->ocontexts[OCON_NODE6]; + for (c = head; c != NULL; c = c->next) + count++; + + *response = count; + + return STATUS_SUCCESS; +} + +/* Check if a node exists */ +int sepol_node_exists(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_node_key_t * key, int *response) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + + int proto; + const char *addr, *mask; + sepol_node_key_unpack(key, &addr, &mask, &proto); + + switch (proto) { + + case SEPOL_PROTO_IP4: + { + head = policydb->ocontexts[OCON_NODE]; + for (c = head; c; c = c->next) { + unsigned int *addr2 = &c->u.node.addr; + unsigned int *mask2 = &c->u.node.mask; + + if (!memcmp(addr, addr2, 4) && + !memcmp(mask, mask2, 4)) { + + *response = 1; + return STATUS_SUCCESS; + } + } + break; + } + case SEPOL_PROTO_IP6: + { + head = policydb->ocontexts[OCON_NODE6]; + for (c = head; c; c = c->next) { + unsigned int *addr2 = c->u.node6.addr; + unsigned int *mask2 = c->u.node6.mask; + + if (!memcmp(addr, addr2, 16) && + !memcmp(mask, mask2, 16)) { + *response = 1; + return STATUS_SUCCESS; + } + } + break; + } + default: + ERR(handle, "unsupported protocol %u", proto); + goto err; + } + + *response = 0; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not check if node %s/%s (%s) exists", + addr, mask, sepol_node_get_proto_str(proto)); + return STATUS_ERR; +} + +/* Query a node */ +int sepol_node_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_node_key_t * key, sepol_node_t ** response) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + + int proto; + const char *addr, *mask; + sepol_node_key_unpack(key, &addr, &mask, &proto); + + switch (proto) { + + case SEPOL_PROTO_IP4: + { + head = policydb->ocontexts[OCON_NODE]; + for (c = head; c; c = c->next) { + unsigned int *addr2 = &c->u.node.addr; + unsigned int *mask2 = &c->u.node.mask; + + if (!memcmp(addr, addr2, 4) && + !memcmp(mask, mask2, 4)) { + + if (node_to_record(handle, policydb, + c, SEPOL_PROTO_IP4, + response) < 0) + goto err; + return STATUS_SUCCESS; + } + } + break; + } + case SEPOL_PROTO_IP6: + { + head = policydb->ocontexts[OCON_NODE6]; + for (c = head; c; c = c->next) { + unsigned int *addr2 = c->u.node6.addr; + unsigned int *mask2 = c->u.node6.mask; + + if (!memcmp(addr, addr2, 16) && + !memcmp(mask, mask2, 16)) { + + if (node_to_record(handle, policydb, + c, SEPOL_PROTO_IP6, + response) < 0) + goto err; + return STATUS_SUCCESS; + } + } + break; + } + default: + ERR(handle, "unsupported protocol %u", proto); + goto err; + } + *response = NULL; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not query node %s/%s (%s)", + addr, mask, sepol_node_get_proto_str(proto)); + return STATUS_ERR; + +} + +/* Load a node into policy */ +int sepol_node_modify(sepol_handle_t * handle, + sepol_policydb_t * p, + const sepol_node_key_t * key, const sepol_node_t * data) +{ + + policydb_t *policydb = &p->p; + ocontext_t *node = NULL; + + int proto; + const char *addr, *mask; + + sepol_node_key_unpack(key, &addr, &mask, &proto); + + if (node_from_record(handle, policydb, &node, data) < 0) + goto err; + + switch (proto) { + + case SEPOL_PROTO_IP4: + { + /* Attach to context list */ + node->next = policydb->ocontexts[OCON_NODE]; + policydb->ocontexts[OCON_NODE] = node; + break; + } + case SEPOL_PROTO_IP6: + { + /* Attach to context list */ + node->next = policydb->ocontexts[OCON_NODE6]; + policydb->ocontexts[OCON_NODE6] = node; + break; + } + default: + ERR(handle, "unsupported protocol %u", proto); + goto err; + } + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not load node %s/%s (%s)", + addr, mask, sepol_node_get_proto_str(proto)); + if (node != NULL) { + context_destroy(&node->context[0]); + free(node); + } + return STATUS_ERR; +} + +int sepol_node_iterate(sepol_handle_t * handle, + const sepol_policydb_t * p, + int (*fn) (const sepol_node_t * node, + void *fn_arg), void *arg) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + sepol_node_t *node = NULL; + int status; + + head = policydb->ocontexts[OCON_NODE]; + for (c = head; c; c = c->next) { + if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP4, &node) + < 0) + goto err; + + /* Invoke handler */ + status = fn(node, arg); + if (status < 0) + goto err; + + sepol_node_free(node); + node = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + head = policydb->ocontexts[OCON_NODE6]; + for (c = head; c; c = c->next) { + if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP6, &node) + < 0) + goto err; + + /* Invoke handler */ + status = fn(node, arg); + if (status < 0) + goto err; + + sepol_node_free(node); + node = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not iterate over nodes"); + sepol_node_free(node); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/nodes.o b/kernel/libsepol/src/nodes.o new file mode 100644 index 00000000..f0030687 Binary files /dev/null and b/kernel/libsepol/src/nodes.o differ diff --git a/kernel/libsepol/src/optimize.c b/kernel/libsepol/src/optimize.c new file mode 100644 index 00000000..b09824a1 --- /dev/null +++ b/kernel/libsepol/src/optimize.c @@ -0,0 +1,467 @@ +/* + * Author: Ondrej Mosnacek + * + * Copyright (C) 2019 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Binary policy optimization. + * + * Defines the policydb_optimize() function, which finds and removes + * redundant rules from the binary policy to reduce its size and potentially + * improve rule matching times. Only rules that are already covered by a + * more general rule are removed. The resulting policy is functionally + * equivalent to the original one. + */ + +#include +#include + +#include "debug.h" +#include "private.h" + +#define TYPE_VEC_INIT_SIZE 16 + +struct type_vec { + uint32_t *types; + unsigned int count, capacity; +}; + +static int type_vec_init(struct type_vec *v) +{ + v->capacity = TYPE_VEC_INIT_SIZE; + v->count = 0; + v->types = calloc(v->capacity, sizeof(*v->types)); + if (!v->types) + return -1; + return 0; +} + +static void type_vec_destroy(struct type_vec *v) +{ + free(v->types); +} + +static int type_vec_append(struct type_vec *v, uint32_t type) +{ + if (v->capacity == v->count) { + unsigned int new_capacity = v->capacity * 2; + uint32_t *new_types = reallocarray(v->types, + new_capacity, + sizeof(*v->types)); + if (!new_types) + return -1; + + v->types = new_types; + v->capacity = new_capacity; + } + + v->types[v->count++] = type; + return 0; +} + +static int type_vec_contains(const struct type_vec *v, uint32_t type) +{ + unsigned int s = 0, e = v->count; + + while (s != e) { + unsigned int mid = (s + e) / 2; + + if (v->types[mid] == type) + return 1; + + if (v->types[mid] < type) + s = mid + 1; + else + e = mid; + } + return 0; +} + +/* builds map: type/attribute -> {all attributes that are a superset of it} */ +static struct type_vec *build_type_map(const policydb_t *p) +{ + unsigned int i, k; + ebitmap_node_t *n; + struct type_vec *map = calloc(p->p_types.nprim, sizeof(*map)); + if (!map) + return NULL; + + for (i = 0; i < p->p_types.nprim; i++) { + if (type_vec_init(&map[i])) + goto err; + + if (!p->type_val_to_struct[i]) + continue; + + if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { + ebitmap_for_each_positive_bit(&p->type_attr_map[i], + n, k) { + if (type_vec_append(&map[i], k)) + goto err; + } + } else { + ebitmap_t *types_i = &p->attr_type_map[i]; + + for (k = 0; k < p->p_types.nprim; k++) { + const ebitmap_t *types_k; + + if (!p->type_val_to_struct[k] || p->type_val_to_struct[k]->flavor != TYPE_ATTRIB) + continue; + + types_k = &p->attr_type_map[k]; + + if (ksu_ebitmap_contains(types_k, types_i)) { + if (type_vec_append(&map[i], k)) + goto err; + } + } + } + } + return map; +err: + for (k = 0; k <= i; k++) + type_vec_destroy(&map[k]); + free(map); + return NULL; +} + +static void destroy_type_map(const policydb_t *p, struct type_vec *type_map) +{ + unsigned int i; + for (i = 0; i < p->p_types.nprim; i++) + type_vec_destroy(&type_map[i]); + free(type_map); +} + +static int process_xperms(uint32_t *p1, const uint32_t *p2) +{ + size_t i; + int ret = 1; + + for (i = 0; i < EXTENDED_PERMS_LEN; i++) { + p1[i] &= ~p2[i]; + if (p1[i] != 0) + ret = 0; + } + return ret; +} + +static int process_avtab_datum(uint16_t specified, + avtab_datum_t *d1, const avtab_datum_t *d2) +{ + /* inverse logic needed for AUDITDENY rules */ + if (specified & AVTAB_AUDITDENY) + return (d1->data |= ~d2->data) == UINT32_C(0xFFFFFFFF); + + if (specified & AVTAB_AV) + return (d1->data &= ~d2->data) == 0; + + if (specified & AVTAB_XPERMS) { + avtab_extended_perms_t *x1 = d1->xperms; + const avtab_extended_perms_t *x2 = d2->xperms; + + if (x1->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + if (x2->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + if (x1->driver != x2->driver) + return 0; + return process_xperms(x1->perms, x2->perms); + } + if (x2->specified == AVTAB_XPERMS_IOCTLDRIVER) + return xperm_test(x1->driver, x2->perms); + } else if (x1->specified == AVTAB_XPERMS_IOCTLDRIVER) { + if (x2->specified == AVTAB_XPERMS_IOCTLFUNCTION) + return 0; + + if (x2->specified == AVTAB_XPERMS_IOCTLDRIVER) + return process_xperms(x1->perms, x2->perms); + } + return 0; + } + return 0; +} + +/* checks if avtab contains a rule that covers the given rule */ +static int is_avrule_redundant(avtab_ptr_t entry, avtab_t *tab, + const struct type_vec *type_map, + unsigned char not_cond) +{ + unsigned int i, k, s_idx, t_idx; + uint32_t st, tt; + avtab_datum_t *d1, *d2; + avtab_key_t key; + + /* we only care about AV rules */ + if (!(entry->key.specified & (AVTAB_AV|AVTAB_XPERMS))) + return 0; + + s_idx = entry->key.source_type - 1; + t_idx = entry->key.target_type - 1; + + key.target_class = entry->key.target_class; + key.specified = entry->key.specified; + + d1 = &entry->datum; + + for (i = 0; i < type_map[s_idx].count; i++) { + st = type_map[s_idx].types[i]; + key.source_type = st + 1; + + for (k = 0; k < type_map[t_idx].count; k++) { + tt = type_map[t_idx].types[k]; + + if (not_cond && s_idx == st && t_idx == tt) + continue; + + key.target_type = tt + 1; + + d2 = ksu_avtab_search(tab, &key); + if (!d2) + continue; + + if (process_avtab_datum(key.specified, d1, d2)) + return 1; + } + } + return 0; +} + +static int is_type_attr(policydb_t *p, unsigned int id) +{ + return p->type_val_to_struct[id]->flavor == TYPE_ATTRIB; +} + +static int is_avrule_with_attr(avtab_ptr_t entry, policydb_t *p) +{ + unsigned int s_idx = entry->key.source_type - 1; + unsigned int t_idx = entry->key.target_type - 1; + + return is_type_attr(p, s_idx) || is_type_attr(p, t_idx); +} + +/* checks if conditional list contains a rule that covers the given rule */ +static int is_cond_rule_redundant(avtab_ptr_t e1, cond_av_list_t *list, + const struct type_vec *type_map) +{ + unsigned int s1, t1, c1, k1, s2, t2, c2, k2; + + /* we only care about AV rules */ + if (!(e1->key.specified & (AVTAB_AV|AVTAB_XPERMS))) + return 0; + + s1 = e1->key.source_type - 1; + t1 = e1->key.target_type - 1; + c1 = e1->key.target_class; + k1 = e1->key.specified; + + for (; list; list = list->next) { + avtab_ptr_t e2 = list->node; + + s2 = e2->key.source_type - 1; + t2 = e2->key.target_type - 1; + c2 = e2->key.target_class; + k2 = e2->key.specified; + + if (k1 != k2 || c1 != c2) + continue; + + if (s1 == s2 && t1 == t2) + continue; + if (!type_vec_contains(&type_map[s1], s2)) + continue; + if (!type_vec_contains(&type_map[t1], t2)) + continue; + + if (process_avtab_datum(k1, &e1->datum, &e2->datum)) + return 1; + } + return 0; +} + +static void optimize_avtab(policydb_t *p, const struct type_vec *type_map) +{ + avtab_t *tab = &p->te_avtab; + unsigned int i; + avtab_ptr_t *cur; + + for (i = 0; i < tab->nslot; i++) { + cur = &tab->htable[i]; + while (*cur) { + if (is_avrule_redundant(*cur, tab, type_map, 1)) { + /* redundant rule -> remove it */ + avtab_ptr_t tmp = *cur; + + *cur = tmp->next; + if (tmp->key.specified & AVTAB_XPERMS) + free(tmp->datum.xperms); + free(tmp); + + tab->nel--; + } else { + /* rule not redundant -> move to next rule */ + cur = &(*cur)->next; + } + } + } +} + +/* find redundant rules in (*cond) and put them into (*del) */ +static void optimize_cond_av_list(cond_av_list_t **cond, cond_av_list_t **del, + policydb_t *p, const struct type_vec *type_map) +{ + cond_av_list_t **listp = cond; + cond_av_list_t *pcov = NULL; + cond_av_list_t **pcov_cur; + + /* + * Separate out all "potentially covering" rules (src or tgt is an attr) + * and move them to the end of the list. This is needed to avoid + * polynomial complexity when almost all rules are expanded. + */ + while (*cond) { + if (is_avrule_with_attr((*cond)->node, p)) { + cond_av_list_t *tmp = *cond; + + *cond = tmp->next; + tmp->next = pcov; + pcov = tmp; + } else { + cond = &(*cond)->next; + } + } + /* link the "potentially covering" rules to the end of the list */ + *cond = pcov; + + /* now go through the list and find the redundant rules */ + cond = listp; + pcov_cur = &pcov; + while (*cond) { + /* needed because pcov itself may get deleted */ + if (*cond == pcov) + pcov_cur = cond; + /* + * First check if covered by an unconditional rule, then also + * check if covered by another rule in the same list. + */ + if (is_avrule_redundant((*cond)->node, &p->te_avtab, type_map, 0) || + is_cond_rule_redundant((*cond)->node, *pcov_cur, type_map)) { + cond_av_list_t *tmp = *cond; + + *cond = tmp->next; + tmp->next = *del; + *del = tmp; + } else { + cond = &(*cond)->next; + } + } +} + +static void optimize_cond_avtab(policydb_t *p, const struct type_vec *type_map) +{ + avtab_t *tab = &p->te_cond_avtab; + unsigned int i; + avtab_ptr_t *cur; + cond_node_t **cond; + cond_av_list_t **avcond, *del = NULL; + + /* First go through all conditionals and collect redundant rules. */ + cond = &p->cond_list; + while (*cond) { + optimize_cond_av_list(&(*cond)->true_list, &del, p, type_map); + optimize_cond_av_list(&(*cond)->false_list, &del, p, type_map); + /* TODO: maybe also check for rules present in both lists */ + + /* nothing left in both lists -> remove the whole conditional */ + if (!(*cond)->true_list && !(*cond)->false_list) { + cond_node_t *cond_tmp = *cond; + + *cond = cond_tmp->next; + cond_node_destroy(cond_tmp); + free(cond_tmp); + } else { + cond = &(*cond)->next; + } + } + + if (!del) + return; + + /* + * Now go through the whole cond_avtab and remove all rules that are + * found in the 'del' list. + */ + for (i = 0; i < tab->nslot; i++) { + cur = &tab->htable[i]; + while (*cur) { + int redundant = 0; + avcond = &del; + while (*avcond) { + if ((*avcond)->node == *cur) { + cond_av_list_t *cond_tmp = *avcond; + + *avcond = cond_tmp->next; + free(cond_tmp); + redundant = 1; + break; + } else { + avcond = &(*avcond)->next; + } + } + if (redundant) { + avtab_ptr_t tmp = *cur; + + *cur = tmp->next; + if (tmp->key.specified & AVTAB_XPERMS) + free(tmp->datum.xperms); + free(tmp); + + tab->nel--; + } else { + cur = &(*cur)->next; + } + } + } +} + +int policydb_optimize(policydb_t *p) +{ + struct type_vec *type_map; + + if (p->policy_type != POLICY_KERN) + return -1; + + if (p->policyvers >= POLICYDB_VERSION_AVTAB && p->policyvers <= POLICYDB_VERSION_PERMISSIVE) { + /* + * For policy versions between 20 and 23, attributes exist in the policy, + * but only in the type_attr_map. This means that there are gaps in both + * the type_val_to_struct and p_type_val_to_name arrays and policy rules + * can refer to those gaps. + */ + ERR(NULL, "Optimizing policy versions between 20 and 23 is not supported"); + return -1; + } + + type_map = build_type_map(p); + if (!type_map) + return -1; + + optimize_avtab(p, type_map); + optimize_cond_avtab(p, type_map); + + destroy_type_map(p, type_map); + return 0; +} diff --git a/kernel/libsepol/src/optimize.o b/kernel/libsepol/src/optimize.o new file mode 100644 index 00000000..ced70753 Binary files /dev/null and b/kernel/libsepol/src/optimize.o differ diff --git a/kernel/libsepol/src/polcaps.c b/kernel/libsepol/src/polcaps.c new file mode 100644 index 00000000..451c9731 --- /dev/null +++ b/kernel/libsepol/src/polcaps.c @@ -0,0 +1,39 @@ +/* + * Policy capability support functions + */ + +#include +#include + +static const char * const polcap_names[] = { + "network_peer_controls", /* POLICYDB_CAP_NETPEER */ + "open_perms", /* POLICYDB_CAP_OPENPERM */ + "extended_socket_class", /* POLICYDB_CAP_EXTSOCKCLASS */ + "always_check_network", /* POLICYDB_CAP_ALWAYSNETWORK */ + "cgroup_seclabel", /* POLICYDB_CAP_SECLABEL */ + "nnp_nosuid_transition", /* POLICYDB_CAP_NNP_NOSUID_TRANSITION */ + "genfs_seclabel_symlinks", /* POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS */ + "ioctl_skip_cloexec", /* POLICYDB_CAP_IOCTL_SKIP_CLOEXEC */ + NULL +}; + +int sepol_polcap_getnum(const char *name) +{ + int capnum; + + for (capnum = 0; capnum <= POLICYDB_CAP_MAX; capnum++) { + if (polcap_names[capnum] == NULL) + continue; + if (strcasecmp(polcap_names[capnum], name) == 0) + return capnum; + } + return -1; +} + +const char *sepol_polcap_getname(unsigned int capnum) +{ + if (capnum > POLICYDB_CAP_MAX) + return NULL; + + return polcap_names[capnum]; +} diff --git a/kernel/libsepol/src/polcaps.o b/kernel/libsepol/src/polcaps.o new file mode 100644 index 00000000..0c0ca720 Binary files /dev/null and b/kernel/libsepol/src/polcaps.o differ diff --git a/kernel/libsepol/src/policydb.c b/kernel/libsepol/src/policydb.c new file mode 100644 index 00000000..606a2feb --- /dev/null +++ b/kernel/libsepol/src/policydb.c @@ -0,0 +1,4630 @@ + +/* Author : Stephen Smalley, */ + +/* + * Updated: Trusted Computer Solutions, Inc. + * + * Support for enhanced MLS infrastructure. + * + * Updated: Frank Mayer and Karl MacMillan + * + * Added conditional policy language extensions + * + * Updated: Red Hat, Inc. James Morris + * Fine-grained netlink support + * IPv6 support + * Code cleanup + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2003 - 2005 Tresys Technology, LLC + * Copyright (C) 2003 - 2007 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Technologies Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * Implementation of the policy database. + */ + +// #include +// #include + +#include +#include +#include +#include +#include + +#include "kernel_to_common.h" +#include "private.h" +#include "debug.h" +#include "mls.h" +#include "policydb_validate.h" + +#define POLICYDB_TARGET_SZ ARRAY_SIZE(policydb_target_strings) +const char * const policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING }; + +/* These need to be updated if SYM_NUM or OCON_NUM changes */ +static const struct policydb_compat_info policydb_compat[] = { + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_BOUNDARY, + .sym_num = SYM_NUM, + .ocon_num = OCON_XEN_PCIDEVICE + 1, + .target_platform = SEPOL_TARGET_XEN, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_XEN_DEVICETREE, + .sym_num = SYM_NUM, + .ocon_num = OCON_XEN_DEVICETREE + 1, + .target_platform = SEPOL_TARGET_XEN, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_BASE, + .sym_num = SYM_NUM - 3, + .ocon_num = OCON_FSUSE + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_BOOL, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_FSUSE + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_IPV6, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_NLCLASS, + .sym_num = SYM_NUM - 2, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_MLS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_AVTAB, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_RANGETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_POLCAP, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_BOUNDARY, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_FILENAME_TRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_ROLETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_DEFAULT_TYPE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_CONSTRAINT_NAMES, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_XPERMS_IOCTL, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_INFINIBAND, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_GLBLUB, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_COMP_FTRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_BASE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_MLS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_MLS_USERS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_POLCAP, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_BOUNDARY, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_FILENAME_TRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_ROLETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_ROLEATTRIB, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_INFINIBAND, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_GLBLUB, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_SELF_TYPETRANS, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_BASE, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_MLS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_MLS_USERS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_POLCAP, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_PERMISSIVE, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_BOUNDARY, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_FILENAME_TRANS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_ROLETRANS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_ROLEATTRIB, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_INFINIBAND, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_GLBLUB, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_SELF_TYPETRANS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, +}; + +#if 0 +static char *symtab_name[SYM_NUM] = { + "common prefixes", + "classes", + "roles", + "types", + "users", + "bools" mls_symtab_names cond_symtab_names +}; +#endif + +static const unsigned int symtab_sizes[SYM_NUM] = { + 2, + 32, + 16, + 512, + 128, + 16, + 16, + 16, +}; + +const struct policydb_compat_info *policydb_lookup_compat(unsigned int version, + unsigned int type, + unsigned int target_platform) +{ + unsigned int i; + const struct policydb_compat_info *info = NULL; + + for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) { + if (policydb_compat[i].version == version && + policydb_compat[i].type == type && + policydb_compat[i].target_platform == target_platform) { + info = &policydb_compat[i]; + break; + } + } + return info; +} + +void type_set_init(type_set_t * x) +{ + memset(x, 0, sizeof(type_set_t)); + ebitmap_init(&x->types); + ebitmap_init(&x->negset); +} + +void type_set_destroy(type_set_t * x) +{ + if (x != NULL) { + ksu_ebitmap_destroy(&x->types); + ksu_ebitmap_destroy(&x->negset); + } +} + +void role_set_init(role_set_t * x) +{ + memset(x, 0, sizeof(role_set_t)); + ebitmap_init(&x->roles); +} + +void role_set_destroy(role_set_t * x) +{ + ksu_ebitmap_destroy(&x->roles); +} + +void role_datum_init(role_datum_t * x) +{ + memset(x, 0, sizeof(role_datum_t)); + ebitmap_init(&x->dominates); + type_set_init(&x->types); + ebitmap_init(&x->cache); + ebitmap_init(&x->roles); +} + +void role_datum_destroy(role_datum_t * x) +{ + if (x != NULL) { + ksu_ebitmap_destroy(&x->dominates); + type_set_destroy(&x->types); + ksu_ebitmap_destroy(&x->cache); + ksu_ebitmap_destroy(&x->roles); + } +} + +void type_datum_init(type_datum_t * x) +{ + memset(x, 0, sizeof(*x)); + ebitmap_init(&x->types); +} + +void type_datum_destroy(type_datum_t * x) +{ + if (x != NULL) { + ksu_ebitmap_destroy(&x->types); + } +} + +void user_datum_init(user_datum_t * x) +{ + memset(x, 0, sizeof(user_datum_t)); + role_set_init(&x->roles); + mls_semantic_range_init(&x->range); + mls_semantic_level_init(&x->dfltlevel); + ebitmap_init(&x->cache); + mls_range_init(&x->exp_range); + mls_level_init(&x->exp_dfltlevel); +} + +void user_datum_destroy(user_datum_t * x) +{ + if (x != NULL) { + role_set_destroy(&x->roles); + mls_semantic_range_destroy(&x->range); + mls_semantic_level_destroy(&x->dfltlevel); + ksu_ebitmap_destroy(&x->cache); + mls_range_destroy(&x->exp_range); + mls_level_destroy(&x->exp_dfltlevel); + } +} + +void level_datum_init(level_datum_t * x) +{ + memset(x, 0, sizeof(level_datum_t)); +} + +void level_datum_destroy(level_datum_t * x __attribute__ ((unused))) +{ + /* the mls_level_t referenced by the level_datum is managed + * separately for now, so there is nothing to destroy */ + return; +} + +void cat_datum_init(cat_datum_t * x) +{ + memset(x, 0, sizeof(cat_datum_t)); +} + +void cat_datum_destroy(cat_datum_t * x __attribute__ ((unused))) +{ + /* it's currently a simple struct - really nothing to destroy */ + return; +} + +void class_perm_node_init(class_perm_node_t * x) +{ + memset(x, 0, sizeof(class_perm_node_t)); +} + +void avrule_init(avrule_t * x) +{ + memset(x, 0, sizeof(avrule_t)); + type_set_init(&x->stypes); + type_set_init(&x->ttypes); +} + +void avrule_destroy(avrule_t * x) +{ + class_perm_node_t *cur, *next; + + if (x == NULL) { + return; + } + type_set_destroy(&x->stypes); + type_set_destroy(&x->ttypes); + + free(x->source_filename); + + next = x->perms; + while (next) { + cur = next; + next = cur->next; + free(cur); + } + + free(x->xperms); +} + +void role_trans_rule_init(role_trans_rule_t * x) +{ + memset(x, 0, sizeof(*x)); + role_set_init(&x->roles); + type_set_init(&x->types); + ebitmap_init(&x->classes); +} + +static void role_trans_rule_destroy(role_trans_rule_t * x) +{ + if (x != NULL) { + role_set_destroy(&x->roles); + type_set_destroy(&x->types); + ksu_ebitmap_destroy(&x->classes); + } +} + +void role_trans_rule_list_destroy(role_trans_rule_t * x) +{ + while (x != NULL) { + role_trans_rule_t *next = x->next; + role_trans_rule_destroy(x); + free(x); + x = next; + } +} + +void filename_trans_rule_init(filename_trans_rule_t * x) +{ + memset(x, 0, sizeof(*x)); + type_set_init(&x->stypes); + type_set_init(&x->ttypes); +} + +static void filename_trans_rule_destroy(filename_trans_rule_t * x) +{ + if (!x) + return; + type_set_destroy(&x->stypes); + type_set_destroy(&x->ttypes); + free(x->name); +} + +void filename_trans_rule_list_destroy(filename_trans_rule_t * x) +{ + filename_trans_rule_t *next; + while (x) { + next = x->next; + filename_trans_rule_destroy(x); + free(x); + x = next; + } +} + +void role_allow_rule_init(role_allow_rule_t * x) +{ + memset(x, 0, sizeof(role_allow_rule_t)); + role_set_init(&x->roles); + role_set_init(&x->new_roles); +} + +void role_allow_rule_destroy(role_allow_rule_t * x) +{ + role_set_destroy(&x->roles); + role_set_destroy(&x->new_roles); +} + +void role_allow_rule_list_destroy(role_allow_rule_t * x) +{ + while (x != NULL) { + role_allow_rule_t *next = x->next; + role_allow_rule_destroy(x); + free(x); + x = next; + } +} + +void range_trans_rule_init(range_trans_rule_t * x) +{ + type_set_init(&x->stypes); + type_set_init(&x->ttypes); + ebitmap_init(&x->tclasses); + mls_semantic_range_init(&x->trange); + x->next = NULL; +} + +void range_trans_rule_destroy(range_trans_rule_t * x) +{ + type_set_destroy(&x->stypes); + type_set_destroy(&x->ttypes); + ksu_ebitmap_destroy(&x->tclasses); + mls_semantic_range_destroy(&x->trange); +} + +void range_trans_rule_list_destroy(range_trans_rule_t * x) +{ + while (x != NULL) { + range_trans_rule_t *next = x->next; + range_trans_rule_destroy(x); + free(x); + x = next; + } +} + +void avrule_list_destroy(avrule_t * x) +{ + avrule_t *next, *cur; + + if (!x) + return; + + next = x; + while (next) { + cur = next; + next = next->next; + avrule_destroy(cur); + free(cur); + } +} + +/* + * Initialize the role table by implicitly adding role 'object_r'. If + * the policy is a module, set object_r's scope to be SCOPE_REQ, + * otherwise set it to SCOPE_DECL. + */ +static int roles_init(policydb_t * p) +{ + char *key = 0; + int rc; + role_datum_t *role; + + role = calloc(1, sizeof(role_datum_t)); + if (!role) { + rc = -ENOMEM; + goto out; + } + key = malloc(strlen(OBJECT_R) + 1); + if (!key) { + rc = -ENOMEM; + goto out_free_role; + } + strcpy(key, OBJECT_R); + rc = ksu_symtab_insert(p, SYM_ROLES, key, role, + (p->policy_type == + POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1, + &role->s.value); + if (rc) + goto out_free_key; + if (role->s.value != OBJECT_R_VAL) { + rc = -EINVAL; + goto out_free_role; + } + out: + return rc; + + out_free_key: + free(key); + out_free_role: + free(role); + goto out; +} + +ignore_unsigned_overflow_ +static inline unsigned long +partial_name_hash(unsigned long c, unsigned long prevhash) +{ + return (prevhash + (c << 4) + (c >> 4)) * 11; +} + +static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k) +{ + const filename_trans_key_t *ft = (const filename_trans_key_t *)k; + unsigned long hash; + unsigned int byte_num; + unsigned char focus; + + hash = ft->ttype ^ ft->tclass; + + byte_num = 0; + while ((focus = ft->name[byte_num++])) + hash = partial_name_hash(focus, hash); + return hash & (h->size - 1); +} + +static int filenametr_cmp(hashtab_t h __attribute__ ((unused)), + const_hashtab_key_t k1, const_hashtab_key_t k2) +{ + const filename_trans_key_t *ft1 = (const filename_trans_key_t *)k1; + const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2; + int v; + + v = spaceship_cmp(ft1->ttype, ft2->ttype); + if (v) + return v; + + v = spaceship_cmp(ft1->tclass, ft2->tclass); + if (v) + return v; + + return strcmp(ft1->name, ft2->name); + +} + +static unsigned int rangetr_hash(hashtab_t h, const_hashtab_key_t k) +{ + const struct range_trans *key = (const struct range_trans *)k; + return (key->source_type + (key->target_type << 3) + + (key->target_class << 5)) & (h->size - 1); +} + +static int rangetr_cmp(hashtab_t h __attribute__ ((unused)), + const_hashtab_key_t k1, const_hashtab_key_t k2) +{ + const struct range_trans *key1 = (const struct range_trans *)k1; + const struct range_trans *key2 = (const struct range_trans *)k2; + int v; + + v = spaceship_cmp(key1->source_type, key2->source_type); + if (v) + return v; + + v = spaceship_cmp(key1->target_type, key2->target_type); + if (v) + return v; + + v = spaceship_cmp(key1->target_class, key2->target_class); + + return v; +} + +/* + * Initialize a policy database structure. + */ +int policydb_init(policydb_t * p) +{ + int i, rc; + + memset(p, 0, sizeof(policydb_t)); + + for (i = 0; i < SYM_NUM; i++) { + p->sym_val_to_name[i] = NULL; + rc = ksu_symtab_init(&p->symtab[i], symtab_sizes[i]); + if (rc) + goto err; + } + + /* initialize the module stuff */ + for (i = 0; i < SYM_NUM; i++) { + if (ksu_symtab_init(&p->scope[i], symtab_sizes[i])) { + goto err; + } + } + if ((p->global = avrule_block_create()) == NULL || + (p->global->branch_list = avrule_decl_create(1)) == NULL) { + goto err; + } + p->decl_val_to_struct = NULL; + + rc = ksu_avtab_init(&p->te_avtab); + if (rc) + goto err; + + rc = roles_init(p); + if (rc) + goto err; + + rc = ksu_cond_policydb_init(p); + if (rc) + goto err; + + p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10)); + if (!p->filename_trans) { + rc = -ENOMEM; + goto err; + } + + p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); + if (!p->range_tr) { + rc = -ENOMEM; + goto err; + } + + ebitmap_init(&p->policycaps); + ebitmap_init(&p->permissive_map); + + return 0; +err: + ksu_hashtab_destroy(p->filename_trans); + ksu_hashtab_destroy(p->range_tr); + for (i = 0; i < SYM_NUM; i++) { + ksu_hashtab_destroy(p->symtab[i].table); + ksu_hashtab_destroy(p->scope[i].table); + } + avrule_block_list_destroy(p->global); + return rc; +} + +int policydb_role_cache(hashtab_key_t key + __attribute__ ((unused)), hashtab_datum_t datum, + void *arg) +{ + policydb_t *p; + role_datum_t *role; + + role = (role_datum_t *) datum; + p = (policydb_t *) arg; + + ksu_ebitmap_destroy(&role->cache); + if (type_set_expand(&role->types, &role->cache, p, 1)) { + return -1; + } + + return 0; +} + +int policydb_user_cache(hashtab_key_t key + __attribute__ ((unused)), hashtab_datum_t datum, + void *arg) +{ + policydb_t *p; + user_datum_t *user; + + user = (user_datum_t *) datum; + p = (policydb_t *) arg; + + ksu_ebitmap_destroy(&user->cache); + if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) { + return -1; + } + + /* we do not expand user's MLS info in kernel policies because the + * semantic representation is not present and we do not expand user's + * MLS info in module policies because all of the necessary mls + * information is not present */ + if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) { + mls_range_destroy(&user->exp_range); + if (mls_semantic_range_expand(&user->range, + &user->exp_range, p, NULL)) { + return -1; + } + + mls_level_destroy(&user->exp_dfltlevel); + if (mls_semantic_level_expand(&user->dfltlevel, + &user->exp_dfltlevel, p, NULL)) { + return -1; + } + } + + return 0; +} + +/* + * The following *_index functions are used to + * define the val_to_name and val_to_struct arrays + * in a policy database structure. The val_to_name + * arrays are used when converting security context + * structures into string representations. The + * val_to_struct arrays are used when the attributes + * of a class, role, or user are needed. + */ + +static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + common_datum_t *comdatum; + + comdatum = (common_datum_t *) datum; + p = (policydb_t *) datap; + if (!value_isvalid(comdatum->s.value, p->p_commons.nprim)) + return -EINVAL; + if (p->p_common_val_to_name[comdatum->s.value - 1] != NULL) + return -EINVAL; + p->p_common_val_to_name[comdatum->s.value - 1] = (char *)key; + + return 0; +} + +static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + class_datum_t *cladatum; + + cladatum = (class_datum_t *) datum; + p = (policydb_t *) datap; + if (!value_isvalid(cladatum->s.value, p->p_classes.nprim)) + return -EINVAL; + if (p->p_class_val_to_name[cladatum->s.value - 1] != NULL) + return -EINVAL; + p->p_class_val_to_name[cladatum->s.value - 1] = (char *)key; + p->class_val_to_struct[cladatum->s.value - 1] = cladatum; + + return 0; +} + +static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + role_datum_t *role; + + role = (role_datum_t *) datum; + p = (policydb_t *) datap; + if (!value_isvalid(role->s.value, p->p_roles.nprim)) + return -EINVAL; + if (p->p_role_val_to_name[role->s.value - 1] != NULL) + return -EINVAL; + p->p_role_val_to_name[role->s.value - 1] = (char *)key; + p->role_val_to_struct[role->s.value - 1] = role; + + return 0; +} + +static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + type_datum_t *typdatum; + + typdatum = (type_datum_t *) datum; + p = (policydb_t *) datap; + + if (typdatum->primary) { + if (!value_isvalid(typdatum->s.value, p->p_types.nprim)) + return -EINVAL; + if (p->p_type_val_to_name[typdatum->s.value - 1] != NULL) + return -EINVAL; + p->p_type_val_to_name[typdatum->s.value - 1] = (char *)key; + p->type_val_to_struct[typdatum->s.value - 1] = typdatum; + } + + return 0; +} + +static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + user_datum_t *usrdatum; + + usrdatum = (user_datum_t *) datum; + p = (policydb_t *) datap; + + if (!value_isvalid(usrdatum->s.value, p->p_users.nprim)) + return -EINVAL; + if (p->p_user_val_to_name[usrdatum->s.value - 1] != NULL) + return -EINVAL; + p->p_user_val_to_name[usrdatum->s.value - 1] = (char *)key; + p->user_val_to_struct[usrdatum->s.value - 1] = usrdatum; + + return 0; +} + +static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + level_datum_t *levdatum; + + levdatum = (level_datum_t *) datum; + p = (policydb_t *) datap; + + if (!levdatum->isalias) { + if (!value_isvalid(levdatum->level->sens, p->p_levels.nprim)) + return -EINVAL; + if (p->p_sens_val_to_name[levdatum->level->sens - 1] != NULL) + return -EINVAL; + p->p_sens_val_to_name[levdatum->level->sens - 1] = (char *)key; + } + + return 0; +} + +static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) +{ + policydb_t *p; + cat_datum_t *catdatum; + + catdatum = (cat_datum_t *) datum; + p = (policydb_t *) datap; + + if (!catdatum->isalias) { + if (!value_isvalid(catdatum->s.value, p->p_cats.nprim)) + return -EINVAL; + if (p->p_cat_val_to_name[catdatum->s.value - 1] != NULL) + return -EINVAL; + p->p_cat_val_to_name[catdatum->s.value - 1] = (char *)key; + } + + return 0; +} + +static int (*index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, + void *datap) = { +common_index, class_index, role_index, type_index, user_index, + ksu_cond_index_bool, sens_index, cat_index,}; + +/* + * Define the common val_to_name array and the class + * val_to_name and val_to_struct arrays in a policy + * database structure. + */ +int policydb_index_classes(policydb_t * p) +{ + free(p->p_common_val_to_name); + p->p_common_val_to_name = (char **) + calloc(p->p_commons.nprim, sizeof(char *)); + if (!p->p_common_val_to_name) + return -1; + + if (ksu_hashtab_map(p->p_commons.table, common_index, p)) + return -1; + + free(p->class_val_to_struct); + p->class_val_to_struct = (class_datum_t **) + calloc(p->p_classes.nprim, sizeof(class_datum_t *)); + if (!p->class_val_to_struct) + return -1; + + free(p->p_class_val_to_name); + p->p_class_val_to_name = (char **) + calloc(p->p_classes.nprim, sizeof(char *)); + if (!p->p_class_val_to_name) + return -1; + + if (ksu_hashtab_map(p->p_classes.table, class_index, p)) + return -1; + + return 0; +} + +int policydb_index_bools(policydb_t * p) +{ + + if (ksu_cond_init_bool_indexes(p) == -1) + return -1; + p->p_bool_val_to_name = (char **) + calloc(p->p_bools.nprim, sizeof(char *)); + if (!p->p_bool_val_to_name) + return -1; + if (ksu_hashtab_map(p->p_bools.table, ksu_cond_index_bool, p)) + return -1; + return 0; +} + +static int policydb_index_decls(sepol_handle_t * handle, policydb_t * p) +{ + avrule_block_t *curblock; + avrule_decl_t *decl; + unsigned int num_decls = 0; + + free(p->decl_val_to_struct); + + for (curblock = p->global; curblock != NULL; curblock = curblock->next) { + for (decl = curblock->branch_list; decl != NULL; + decl = decl->next) { + num_decls++; + } + } + + p->decl_val_to_struct = + calloc(num_decls, sizeof(*(p->decl_val_to_struct))); + if (!p->decl_val_to_struct) { + return -1; + } + + for (curblock = p->global; curblock != NULL; curblock = curblock->next) { + for (decl = curblock->branch_list; decl != NULL; + decl = decl->next) { + if (!value_isvalid(decl->decl_id, num_decls)) { + ERR(handle, "invalid decl ID %u", decl->decl_id); + return -1; + } + if (p->decl_val_to_struct[decl->decl_id - 1] != NULL) { + ERR(handle, "duplicated decl ID %u", decl->decl_id); + return -1; + } + p->decl_val_to_struct[decl->decl_id - 1] = decl; + } + } + + return 0; +} + +/* + * Define the other val_to_name and val_to_struct arrays + * in a policy database structure. + */ +int policydb_index_others(sepol_handle_t * handle, + policydb_t * p, unsigned verbose) +{ + int i; + + if (verbose) { + INFO(handle, + "security: %d users, %d roles, %d types, %d bools", + p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, + p->p_bools.nprim); + + if (p->mls) + INFO(handle, "security: %d sens, %d cats", + p->p_levels.nprim, p->p_cats.nprim); + + INFO(handle, "security: %d classes, %d rules, %d cond rules", + p->p_classes.nprim, p->te_avtab.nel, p->te_cond_avtab.nel); + } +#if 0 + ksu_avtab_hash_eval(&p->te_avtab, "rules"); + for (i = 0; i < SYM_NUM; i++) + hashtab_hash_eval(p->symtab[i].table, symtab_name[i]); +#endif + + free(p->role_val_to_struct); + p->role_val_to_struct = (role_datum_t **) + calloc(p->p_roles.nprim, sizeof(role_datum_t *)); + if (!p->role_val_to_struct) + return -1; + + free(p->user_val_to_struct); + p->user_val_to_struct = (user_datum_t **) + calloc(p->p_users.nprim, sizeof(user_datum_t *)); + if (!p->user_val_to_struct) + return -1; + + free(p->type_val_to_struct); + p->type_val_to_struct = (type_datum_t **) + calloc(p->p_types.nprim, sizeof(type_datum_t *)); + if (!p->type_val_to_struct) + return -1; + + if (ksu_cond_init_bool_indexes(p)) + return -1; + + for (i = SYM_ROLES; i < SYM_NUM; i++) { + free(p->sym_val_to_name[i]); + p->sym_val_to_name[i] = NULL; + if (p->symtab[i].nprim) { + p->sym_val_to_name[i] = (char **) + calloc(p->symtab[i].nprim, sizeof(char *)); + if (!p->sym_val_to_name[i]) + return -1; + if (ksu_hashtab_map(p->symtab[i].table, index_f[i], p)) + return -1; + } + } + + /* This pre-expands the roles and users for context validity checking */ + if (ksu_hashtab_map(p->p_roles.table, policydb_role_cache, p)) + return -1; + + if (ksu_hashtab_map(p->p_users.table, policydb_user_cache, p)) + return -1; + + return 0; +} + +/* + * The following *_destroy functions are used to + * free any memory allocated for each kind of + * symbol data in the policy database. + */ + +static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + if (key) + free(key); + free(datum); + return 0; +} + +static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + common_datum_t *comdatum; + + if (key) + free(key); + comdatum = (common_datum_t *) datum; + (void)ksu_hashtab_map(comdatum->permissions.table, perm_destroy, 0); + ksu_hashtab_destroy(comdatum->permissions.table); + free(datum); + return 0; +} + +static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + class_datum_t *cladatum; + constraint_node_t *constraint, *ctemp; + + if (key) + free(key); + cladatum = (class_datum_t *) datum; + if (cladatum == NULL) { + return 0; + } + (void)ksu_hashtab_map(cladatum->permissions.table, perm_destroy, 0); + ksu_hashtab_destroy(cladatum->permissions.table); + constraint = cladatum->constraints; + while (constraint) { + constraint_expr_destroy(constraint->expr); + ctemp = constraint; + constraint = constraint->next; + free(ctemp); + } + + constraint = cladatum->validatetrans; + while (constraint) { + constraint_expr_destroy(constraint->expr); + ctemp = constraint; + constraint = constraint->next; + free(ctemp); + } + + if (cladatum->comkey) + free(cladatum->comkey); + free(datum); + return 0; +} + +static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + free(key); + role_datum_destroy((role_datum_t *) datum); + free(datum); + return 0; +} + +static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + free(key); + type_datum_destroy((type_datum_t *) datum); + free(datum); + return 0; +} + +static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + free(key); + user_datum_destroy((user_datum_t *) datum); + free(datum); + return 0; +} + +static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + level_datum_t *levdatum; + + if (key) + free(key); + levdatum = (level_datum_t *) datum; + mls_level_destroy(levdatum->level); + free(levdatum->level); + level_datum_destroy(levdatum); + free(levdatum); + return 0; +} + +static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + if (key) + free(key); + cat_datum_destroy((cat_datum_t *) datum); + free(datum); + return 0; +} + +static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, + void *datap) = { +common_destroy, class_destroy, role_destroy, type_destroy, user_destroy, + ksu_cond_destroy_bool, sens_destroy, cat_destroy,}; + +static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum, + void *p __attribute__ ((unused))) +{ + filename_trans_key_t *ft = (filename_trans_key_t *)key; + filename_trans_datum_t *fd = datum, *next; + + free(ft->name); + free(key); + do { + next = fd->next; + ksu_ebitmap_destroy(&fd->stypes); + free(fd); + fd = next; + } while (fd); + return 0; +} + +static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum, + void *p __attribute__ ((unused))) +{ + struct mls_range *rt = (struct mls_range *)datum; + free(key); + ksu_ebitmap_destroy(&rt->level[0].cat); + ksu_ebitmap_destroy(&rt->level[1].cat); + free(datum); + return 0; +} + +static void ocontext_selinux_free(ocontext_t **ocontexts) +{ + ocontext_t *c, *ctmp; + int i; + + for (i = 0; i < OCON_NUM; i++) { + c = ocontexts[i]; + while (c) { + ctmp = c; + c = c->next; + context_destroy(&ctmp->context[0]); + context_destroy(&ctmp->context[1]); + if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF + || i == OCON_FSUSE) + free(ctmp->u.name); + else if (i == OCON_IBENDPORT) + free(ctmp->u.ibendport.dev_name); + free(ctmp); + } + } +} + +static void ocontext_xen_free(ocontext_t **ocontexts) +{ + ocontext_t *c, *ctmp; + int i; + + for (i = 0; i < OCON_NUM; i++) { + c = ocontexts[i]; + while (c) { + ctmp = c; + c = c->next; + context_destroy(&ctmp->context[0]); + context_destroy(&ctmp->context[1]); + if (i == OCON_ISID || i == OCON_XEN_DEVICETREE) + free(ctmp->u.name); + free(ctmp); + } + } +} + +/* + * Free any memory allocated by a policy database structure. + */ +void ksu_policydb_destroy(policydb_t * p) +{ + ocontext_t *c, *ctmp; + genfs_t *g, *gtmp; + unsigned int i; + role_allow_t *ra, *lra = NULL; + role_trans_t *tr, *ltr = NULL; + + if (!p) + return; + + ksu_ebitmap_destroy(&p->policycaps); + + ksu_ebitmap_destroy(&p->permissive_map); + + symtabs_destroy(p->symtab); + + for (i = 0; i < SYM_NUM; i++) { + if (p->sym_val_to_name[i]) + free(p->sym_val_to_name[i]); + } + + if (p->class_val_to_struct) + free(p->class_val_to_struct); + if (p->role_val_to_struct) + free(p->role_val_to_struct); + if (p->user_val_to_struct) + free(p->user_val_to_struct); + if (p->type_val_to_struct) + free(p->type_val_to_struct); + free(p->decl_val_to_struct); + + for (i = 0; i < SYM_NUM; i++) { + (void)ksu_hashtab_map(p->scope[i].table, scope_destroy, 0); + ksu_hashtab_destroy(p->scope[i].table); + } + avrule_block_list_destroy(p->global); + free(p->name); + free(p->version); + + ksu_avtab_destroy(&p->te_avtab); + + if (p->target_platform == SEPOL_TARGET_SELINUX) + ocontext_selinux_free(p->ocontexts); + else if (p->target_platform == SEPOL_TARGET_XEN) + ocontext_xen_free(p->ocontexts); + + g = p->genfs; + while (g) { + free(g->fstype); + c = g->head; + while (c) { + ctmp = c; + c = c->next; + context_destroy(&ctmp->context[0]); + free(ctmp->u.name); + free(ctmp); + } + gtmp = g; + g = g->next; + free(gtmp); + } + ksu_cond_policydb_destroy(p); + + for (tr = p->role_tr; tr; tr = tr->next) { + if (ltr) + free(ltr); + ltr = tr; + } + if (ltr) + free(ltr); + + for (ra = p->role_allow; ra; ra = ra->next) { + if (lra) + free(lra); + lra = ra; + } + if (lra) + free(lra); + + ksu_hashtab_map(p->filename_trans, filenametr_destroy, NULL); + ksu_hashtab_destroy(p->filename_trans); + + ksu_hashtab_map(p->range_tr, range_tr_destroy, NULL); + ksu_hashtab_destroy(p->range_tr); + + if (p->type_attr_map) { + for (i = 0; i < p->p_types.nprim; i++) { + ksu_ebitmap_destroy(&p->type_attr_map[i]); + } + free(p->type_attr_map); + } + + if (p->attr_type_map) { + for (i = 0; i < p->p_types.nprim; i++) { + ksu_ebitmap_destroy(&p->attr_type_map[i]); + } + free(p->attr_type_map); + } + + return; +} + +void symtabs_destroy(symtab_t * symtab) +{ + int i; + for (i = 0; i < SYM_NUM; i++) { + (void)ksu_hashtab_map(symtab[i].table, destroy_f[i], 0); + ksu_hashtab_destroy(symtab[i].table); + } +} + +int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p + __attribute__ ((unused))) +{ + scope_datum_t *cur = (scope_datum_t *) datum; + free(key); + if (cur != NULL) { + free(cur->decl_ids); + } + free(cur); + return 0; +} + +/* + * Load the initial SIDs specified in a policy database + * structure into a SID table. + */ +int ksu_policydb_load_isids(policydb_t * p, sidtab_t * s) +{ + ocontext_t *head, *c; + + if (sepol_sidtab_init(s)) { + ERR(NULL, "out of memory on SID table init"); + return -1; + } + + head = p->ocontexts[OCON_ISID]; + for (c = head; c; c = c->next) { + if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) { + ERR(NULL, "unable to load initial SID %s", c->u.name); + return -1; + } + } + + return 0; +} + +/* Declare a symbol for a certain avrule_block context. Insert it + * into a symbol table for a policy. This function will handle + * inserting the appropriate scope information in addition to + * inserting the symbol into the hash table. + * + * arguments: + * policydb_t *pol module policy to modify + * uint32_t sym the symbole table for insertion (SYM_*) + * hashtab_key_t key the key for the symbol - not cloned + * hashtab_datum_t data the data for the symbol - not cloned + * scope scope of this symbol, either SCOPE_REQ or SCOPE_DECL + * avrule_decl_id identifier for this symbol's encapsulating declaration + * value (out) assigned value to the symbol (if value is not NULL) + * + * returns: + * 0 success + * 1 success, but symbol already existed as a requirement + * (datum was not inserted and needs to be free()d) + * -1 general error + * -2 scope conflicted + * -ENOMEM memory error + * error codes from hashtab_insert + */ +int ksu_symtab_insert(policydb_t * pol, uint32_t sym, + hashtab_key_t key, hashtab_datum_t datum, + uint32_t scope, uint32_t avrule_decl_id, uint32_t * value) +{ + int rc, retval = 0; + unsigned int i; + scope_datum_t *scope_datum; + + /* check if the symbol is already there. multiple + * declarations of non-roles/non-users are illegal, but + * multiple requires are allowed. */ + + /* FIX ME - the failures after the hashtab_insert will leave + * the policy in a inconsistent state. */ + rc = hashtab_insert(pol->symtab[sym].table, key, datum); + if (rc == SEPOL_OK) { + /* if no value is passed in the symbol is not primary + * (i.e. aliases) */ + if (value) + *value = ++pol->symtab[sym].nprim; + } else if (rc == SEPOL_EEXIST) { + retval = 1; /* symbol not added -- need to free() later */ + } else { + return rc; + } + + /* get existing scope information; if there is not one then + * create it */ + scope_datum = + (scope_datum_t *) hashtab_search(pol->scope[sym].table, key); + if (scope_datum == NULL) { + hashtab_key_t key2 = strdup((char *)key); + if (!key2) + return -ENOMEM; + if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) { + free(key2); + return -ENOMEM; + } + scope_datum->scope = scope; + scope_datum->decl_ids = NULL; + scope_datum->decl_ids_len = 0; + if ((rc = + hashtab_insert(pol->scope[sym].table, key2, + scope_datum)) != 0) { + free(key2); + free(scope_datum); + return rc; + } + } else if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_DECL) { + /* disallow multiple declarations for non-roles/users */ + if (sym != SYM_ROLES && sym != SYM_USERS) { + return -2; + } + /* Further confine that a role attribute can't have the same + * name as another regular role, and a role attribute can't + * be declared more than once. */ + if (sym == SYM_ROLES) { + role_datum_t *base_role; + role_datum_t *cur_role = (role_datum_t *)datum; + + base_role = (role_datum_t *) + hashtab_search(pol->symtab[sym].table, + key); + assert(base_role != NULL); + + if (!((base_role->flavor == ROLE_ROLE) && + (cur_role->flavor == ROLE_ROLE))) { + /* Only regular roles are allowed to have + * multiple declarations. */ + return -2; + } + } + } else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) { + scope_datum->scope = SCOPE_DECL; + } + + /* search through the pre-existing list to avoid adding duplicates */ + for (i = 0; i < scope_datum->decl_ids_len; i++) { + if (scope_datum->decl_ids[i] == avrule_decl_id) { + /* already there, so don't modify its scope */ + return retval; + } + } + + if (add_i_to_a(avrule_decl_id, + &scope_datum->decl_ids_len, + &scope_datum->decl_ids) == -1) { + return -ENOMEM; + } + + if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_REQ) { + /* Need to keep the decl at the end of the list */ + uint32_t len, tmp; + len = scope_datum->decl_ids_len; + if (len < 2) { + /* This should be impossible here */ + return -1; + } + tmp = scope_datum->decl_ids[len-2]; + scope_datum->decl_ids[len-2] = scope_datum->decl_ids[len-1]; + scope_datum->decl_ids[len-1] = tmp; + } + + return retval; +} + +static int type_set_or(type_set_t * dst, const type_set_t * a, const type_set_t * b) +{ + type_set_init(dst); + + if (ebitmap_or(&dst->types, &a->types, &b->types)) { + return -1; + } + if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) { + return -1; + } + + dst->flags |= a->flags; + dst->flags |= b->flags; + + return 0; +} + +int type_set_cpy(type_set_t * dst, const type_set_t * src) +{ + type_set_init(dst); + + dst->flags = src->flags; + if (ksu_ebitmap_cpy(&dst->types, &src->types)) + return -1; + if (ksu_ebitmap_cpy(&dst->negset, &src->negset)) + return -1; + + return 0; +} + +int type_set_or_eq(type_set_t * dst, const type_set_t * other) +{ + int ret; + type_set_t tmp; + + if (type_set_or(&tmp, dst, other)) + return -1; + type_set_destroy(dst); + ret = type_set_cpy(dst, &tmp); + type_set_destroy(&tmp); + + return ret; +} + +/***********************************************************************/ +/* everything below is for policy reads */ + +/* The following are read functions for module structures */ + +static int role_set_read(role_set_t * r, struct policy_file *fp) +{ + uint32_t buf[1]; + int rc; + + if (ksu_ebitmap_read(&r->roles, fp)) + return -1; + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + r->flags = le32_to_cpu(buf[0]); + + return 0; +} + +static int type_set_read(type_set_t * t, struct policy_file *fp) +{ + uint32_t buf[1]; + int rc; + + if (ksu_ebitmap_read(&t->types, fp)) + return -1; + if (ksu_ebitmap_read(&t->negset, fp)) + return -1; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + t->flags = le32_to_cpu(buf[0]); + + return 0; +} + +/* + * Read a MLS range structure from a policydb binary + * representation file. + */ +static int mls_read_range_helper(mls_range_t * r, struct policy_file *fp) +{ + uint32_t buf[2], items; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto out; + + items = le32_to_cpu(buf[0]); + if (items > ARRAY_SIZE(buf)) { + ERR(fp->handle, "range overflow"); + rc = -EINVAL; + goto out; + } + rc = next_entry(buf, fp, sizeof(uint32_t) * items); + if (rc < 0) { + ERR(fp->handle, "truncated range"); + goto out; + } + r->level[0].sens = le32_to_cpu(buf[0]); + if (items > 1) + r->level[1].sens = le32_to_cpu(buf[1]); + else + r->level[1].sens = r->level[0].sens; + + rc = ksu_ebitmap_read(&r->level[0].cat, fp); + if (rc) { + ERR(fp->handle, "error reading low categories"); + goto out; + } + if (items > 1) { + rc = ksu_ebitmap_read(&r->level[1].cat, fp); + if (rc) { + ERR(fp->handle, "error reading high categories"); + goto bad_high; + } + } else { + rc = ksu_ebitmap_cpy(&r->level[1].cat, &r->level[0].cat); + if (rc) { + ERR(fp->handle, "out of memory"); + goto bad_high; + } + } + + rc = 0; + out: + return rc; + bad_high: + ksu_ebitmap_destroy(&r->level[0].cat); + goto out; +} + +/* + * Read a semantic MLS level structure from a policydb binary + * representation file. + */ +static int mls_read_semantic_level_helper(mls_semantic_level_t * l, + struct policy_file *fp) +{ + uint32_t buf[2], ncat; + unsigned int i; + mls_semantic_cat_t *cat; + int rc; + + mls_semantic_level_init(l); + + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) { + ERR(fp->handle, "truncated level"); + goto bad; + } + l->sens = le32_to_cpu(buf[0]); + + ncat = le32_to_cpu(buf[1]); + for (i = 0; i < ncat; i++) { + cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); + if (!cat) { + ERR(fp->handle, "out of memory"); + goto bad; + } + + mls_semantic_cat_init(cat); + cat->next = l->cat; + l->cat = cat; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) { + ERR(fp->handle, "error reading level categories"); + goto bad; + } + cat->low = le32_to_cpu(buf[0]); + cat->high = le32_to_cpu(buf[1]); + } + + return 0; + + bad: + return -EINVAL; +} + +/* + * Read a semantic MLS range structure from a policydb binary + * representation file. + */ +static int mls_read_semantic_range_helper(mls_semantic_range_t * r, + struct policy_file *fp) +{ + int rc; + + rc = mls_read_semantic_level_helper(&r->level[0], fp); + if (rc) + return rc; + + rc = mls_read_semantic_level_helper(&r->level[1], fp); + + return rc; +} + +static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl) +{ + unsigned int i; + ebitmap_node_t *cnode; + mls_semantic_cat_t *open_cat = NULL; + + mls_semantic_level_init(sl); + sl->sens = l->sens; + ebitmap_for_each_bit(&l->cat, cnode, i) { + if (ebitmap_node_get_bit(cnode, i)) { + if (open_cat) + continue; + open_cat = (mls_semantic_cat_t *) + malloc(sizeof(mls_semantic_cat_t)); + if (!open_cat) + return -1; + + mls_semantic_cat_init(open_cat); + open_cat->low = i + 1; + open_cat->next = sl->cat; + sl->cat = open_cat; + } else { + if (!open_cat) + continue; + open_cat->high = i; + open_cat = NULL; + } + } + if (open_cat) + open_cat->high = i; + + return 0; +} + +static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr) +{ + if (mls_level_to_semantic(&r->level[0], &sr->level[0])) + return -1; + + if (mls_level_to_semantic(&r->level[1], &sr->level[1])) + return -1; + + return 0; +} + +/* + * Read and validate a security context structure + * from a policydb binary representation file. + */ +static int context_read_and_validate(context_struct_t * c, + policydb_t * p, struct policy_file *fp) +{ + uint32_t buf[3]; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) { + ERR(fp->handle, "context truncated"); + return -1; + } + c->user = le32_to_cpu(buf[0]); + c->role = le32_to_cpu(buf[1]); + c->type = le32_to_cpu(buf[2]); + if ((p->policy_type == POLICY_KERN + && p->policyvers >= POLICYDB_VERSION_MLS) + || (p->policy_type == POLICY_BASE + && p->policyvers >= MOD_POLICYDB_VERSION_MLS)) { + if (mls_read_range_helper(&c->range, fp)) { + ERR(fp->handle, "error reading MLS range " + "of context"); + return -1; + } + } + + if (!ksu_policydb_context_isvalid(p, c)) { + ERR(fp->handle, "invalid security context"); + context_destroy(c); + return -1; + } + return 0; +} + +/* + * The following *_read functions are used to + * read the symbol data from a policy database + * binary representation file. + */ + +static int perm_read(policydb_t * p + __attribute__ ((unused)), hashtab_t h, + struct policy_file *fp, uint32_t nprim) +{ + char *key = 0; + perm_datum_t *perdatum; + uint32_t buf[2]; + size_t len; + int rc; + + perdatum = calloc(1, sizeof(perm_datum_t)); + if (!perdatum) + return -1; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[0]); + if(str_read(&key, fp, len)) + goto bad; + + perdatum->s.value = le32_to_cpu(buf[1]); + if (!value_isvalid(perdatum->s.value, nprim)) + goto bad; + + if (hashtab_insert(h, key, perdatum)) + goto bad; + + return 0; + + bad: + perm_destroy(key, perdatum, NULL); + return -1; +} + +static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) +{ + char *key = 0; + common_datum_t *comdatum; + uint32_t buf[4]; + size_t len, nel; + unsigned int i; + int rc; + + comdatum = calloc(1, sizeof(common_datum_t)); + if (!comdatum) + return -1; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 4); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + + comdatum->s.value = le32_to_cpu(buf[1]); + + if (ksu_symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) + goto bad; + comdatum->permissions.nprim = le32_to_cpu(buf[2]); + if (comdatum->permissions.nprim > PERM_SYMTAB_SIZE) + goto bad; + nel = le32_to_cpu(buf[3]); + + key = malloc(len + 1); + if (!key) + goto bad; + rc = next_entry(key, fp, len); + if (rc < 0) + goto bad; + key[len] = 0; + + for (i = 0; i < nel; i++) { + if (perm_read(p, comdatum->permissions.table, fp, comdatum->permissions.nprim)) + goto bad; + } + + if (hashtab_insert(h, key, comdatum)) + goto bad; + + return 0; + + bad: + common_destroy(key, comdatum, NULL); + return -1; +} + +static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep, + unsigned int ncons, + int allowxtarget, struct policy_file *fp) +{ + constraint_node_t *c, *lc; + constraint_expr_t *e, *le; + uint32_t buf[3]; + size_t nexpr; + unsigned int i, j; + int rc, depth; + + lc = NULL; + for (i = 0; i < ncons; i++) { + c = calloc(1, sizeof(constraint_node_t)); + if (!c) + return -1; + + if (lc) + lc->next = c; + else + *nodep = c; + + rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); + if (rc < 0) + return -1; + c->permissions = le32_to_cpu(buf[0]); + nexpr = le32_to_cpu(buf[1]); + le = NULL; + depth = -1; + for (j = 0; j < nexpr; j++) { + e = malloc(sizeof(constraint_expr_t)); + if (!e) + return -1; + if (constraint_expr_init(e) == -1) { + free(e); + return -1; + } + if (le) { + le->next = e; + } else { + c->expr = e; + } + + rc = next_entry(buf, fp, (sizeof(uint32_t) * 3)); + if (rc < 0) + return -1; + e->expr_type = le32_to_cpu(buf[0]); + e->attr = le32_to_cpu(buf[1]); + e->op = le32_to_cpu(buf[2]); + + switch (e->expr_type) { + case CEXPR_NOT: + if (depth < 0) + return -1; + break; + case CEXPR_AND: + case CEXPR_OR: + if (depth < 1) + return -1; + depth--; + break; + case CEXPR_ATTR: + if (depth == (CEXPR_MAXDEPTH - 1)) + return -1; + depth++; + break; + case CEXPR_NAMES: + if (!allowxtarget && (e->attr & CEXPR_XTARGET)) + return -1; + if (depth == (CEXPR_MAXDEPTH - 1)) + return -1; + depth++; + if (ksu_ebitmap_read(&e->names, fp)) + return -1; + if (p->policy_type != POLICY_KERN && + type_set_read(e->type_names, fp)) + return -1; + else if (p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES && + type_set_read(e->type_names, fp)) + return -1; + break; + default: + return -1; + } + le = e; + } + if (depth != 0) + return -1; + lc = c; + } + + return 0; +} + +static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) +{ + char *key = 0; + class_datum_t *cladatum; + uint32_t buf[6]; + size_t len, len2, ncons, nel; + unsigned int i; + int rc; + + cladatum = (class_datum_t *) calloc(1, sizeof(class_datum_t)); + if (!cladatum) + return -1; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 6); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + len2 = le32_to_cpu(buf[1]); + if (is_saturated(len2)) + goto bad; + cladatum->s.value = le32_to_cpu(buf[2]); + + if (ksu_symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) + goto bad; + cladatum->permissions.nprim = le32_to_cpu(buf[3]); + if (cladatum->permissions.nprim > PERM_SYMTAB_SIZE) + goto bad; + nel = le32_to_cpu(buf[4]); + + ncons = le32_to_cpu(buf[5]); + + key = malloc(len + 1); + if (!key) + goto bad; + rc = next_entry(key, fp, len); + if (rc < 0) + goto bad; + key[len] = 0; + + if (len2) { + cladatum->comkey = malloc(len2 + 1); + if (!cladatum->comkey) + goto bad; + rc = next_entry(cladatum->comkey, fp, len2); + if (rc < 0) + goto bad; + cladatum->comkey[len2] = 0; + + cladatum->comdatum = hashtab_search(p->p_commons.table, + cladatum->comkey); + if (!cladatum->comdatum) { + ERR(fp->handle, "unknown common %s", cladatum->comkey); + goto bad; + } + } + for (i = 0; i < nel; i++) { + if (perm_read(p, cladatum->permissions.table, fp, cladatum->permissions.nprim)) + goto bad; + } + + if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp)) + goto bad; + + if ((p->policy_type == POLICY_KERN + && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) + || (p->policy_type == POLICY_BASE + && p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { + /* grab the validatetrans rules */ + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + ncons = le32_to_cpu(buf[0]); + if (read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp)) + goto bad; + } + + if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) + goto bad; + cladatum->default_user = le32_to_cpu(buf[0]); + cladatum->default_role = le32_to_cpu(buf[1]); + cladatum->default_range = le32_to_cpu(buf[2]); + } + + if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + cladatum->default_type = le32_to_cpu(buf[0]); + } + + if (hashtab_insert(h, key, cladatum)) + goto bad; + + return 0; + + bad: + class_destroy(key, cladatum, NULL); + return -1; +} + +static int role_read(policydb_t * p, hashtab_t h, struct policy_file *fp) +{ + char *key = 0; + role_datum_t *role; + uint32_t buf[3]; + size_t len; + int rc, to_read = 2; + + role = calloc(1, sizeof(role_datum_t)); + if (!role) + return -1; + + if (policydb_has_boundary_feature(p)) + to_read = 3; + + rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + + role->s.value = le32_to_cpu(buf[1]); + if (policydb_has_boundary_feature(p)) + role->bounds = le32_to_cpu(buf[2]); + + key = malloc(len + 1); + if (!key) + goto bad; + rc = next_entry(key, fp, len); + if (rc < 0) + goto bad; + key[len] = 0; + + if (ksu_ebitmap_read(&role->dominates, fp)) + goto bad; + + if (p->policy_type == POLICY_KERN) { + if (ksu_ebitmap_read(&role->types.types, fp)) + goto bad; + } else { + if (type_set_read(&role->types, fp)) + goto bad; + } + + if (p->policy_type != POLICY_KERN && + p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + + role->flavor = le32_to_cpu(buf[0]); + + if (ksu_ebitmap_read(&role->roles, fp)) + goto bad; + } + + if (strcmp(key, OBJECT_R) == 0) { + if (role->s.value != OBJECT_R_VAL) { + ERR(fp->handle, "role %s has wrong value %d", + OBJECT_R, role->s.value); + role_destroy(key, role, NULL); + return -1; + } + role_destroy(key, role, NULL); + return 0; + } + + if (hashtab_insert(h, key, role)) + goto bad; + + return 0; + + bad: + role_destroy(key, role, NULL); + return -1; +} + +static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp) +{ + char *key = 0; + type_datum_t *typdatum; + uint32_t buf[5]; + size_t len; + int rc, to_read; + int pos = 0; + + typdatum = calloc(1, sizeof(type_datum_t)); + if (!typdatum) + return -1; + + if (policydb_has_boundary_feature(p)) { + if (p->policy_type != POLICY_KERN + && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) + to_read = 5; + else + to_read = 4; + } + else if (p->policy_type == POLICY_KERN) + to_read = 3; + else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) + to_read = 5; + else + to_read = 4; + + rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[pos]); + if (zero_or_saturated(len)) + goto bad; + + typdatum->s.value = le32_to_cpu(buf[++pos]); + if (policydb_has_boundary_feature(p)) { + uint32_t properties; + + if (p->policy_type != POLICY_KERN + && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) { + typdatum->primary = le32_to_cpu(buf[++pos]); + properties = le32_to_cpu(buf[++pos]); + } + else { + properties = le32_to_cpu(buf[++pos]); + + if (properties & TYPEDATUM_PROPERTY_PRIMARY) + typdatum->primary = 1; + } + + if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE) + typdatum->flavor = TYPE_ATTRIB; + if (properties & TYPEDATUM_PROPERTY_ALIAS + && p->policy_type != POLICY_KERN) + typdatum->flavor = TYPE_ALIAS; + if (properties & TYPEDATUM_PROPERTY_PERMISSIVE + && p->policy_type != POLICY_KERN) + typdatum->flags |= TYPE_FLAGS_PERMISSIVE; + + typdatum->bounds = le32_to_cpu(buf[++pos]); + } else { + typdatum->primary = le32_to_cpu(buf[++pos]); + if (p->policy_type != POLICY_KERN) { + typdatum->flavor = le32_to_cpu(buf[++pos]); + if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) + typdatum->flags = le32_to_cpu(buf[++pos]); + } + } + + if (p->policy_type != POLICY_KERN) { + if (ksu_ebitmap_read(&typdatum->types, fp)) + goto bad; + } + + key = malloc(len + 1); + if (!key) + goto bad; + rc = next_entry(key, fp, len); + if (rc < 0) + goto bad; + key[len] = 0; + + if (hashtab_insert(h, key, typdatum)) + goto bad; + + return 0; + + bad: + type_destroy(key, typdatum, NULL); + return -1; +} + +static int role_trans_read(policydb_t *p, struct policy_file *fp) +{ + role_trans_t **t = &p->role_tr; + unsigned int i; + uint32_t buf[3], nel; + role_trans_t *tr, *ltr; + int rc; + int new_roletr = (p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_ROLETRANS); + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + ltr = NULL; + for (i = 0; i < nel; i++) { + tr = calloc(1, sizeof(struct role_trans)); + if (!tr) { + return -1; + } + if (ltr) { + ltr->next = tr; + } else { + *t = tr; + } + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) + return -1; + tr->role = le32_to_cpu(buf[0]); + tr->type = le32_to_cpu(buf[1]); + tr->new_role = le32_to_cpu(buf[2]); + if (new_roletr) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + tr->tclass = le32_to_cpu(buf[0]); + } else + tr->tclass = p->process_class; + ltr = tr; + } + return 0; +} + +static int role_allow_read(role_allow_t ** r, struct policy_file *fp) +{ + unsigned int i; + uint32_t buf[2], nel; + role_allow_t *ra, *lra; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + lra = NULL; + for (i = 0; i < nel; i++) { + ra = calloc(1, sizeof(struct role_allow)); + if (!ra) { + return -1; + } + if (lra) { + lra->next = ra; + } else { + *r = ra; + } + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + ra->role = le32_to_cpu(buf[0]); + ra->new_role = le32_to_cpu(buf[1]); + lra = ra; + } + return 0; +} + +int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype, + uint32_t tclass, const char *name, + char **name_alloc, uint32_t otype, + uint32_t *present_otype) +{ + filename_trans_key_t *ft, key; + filename_trans_datum_t *datum, *last; + + key.ttype = ttype; + key.tclass = tclass; + key.name = (char *)name; + + last = NULL; + datum = hashtab_search(p->filename_trans, (hashtab_key_t)&key); + while (datum) { + if (ksu_ebitmap_get_bit(&datum->stypes, stype - 1)) { + if (present_otype) + *present_otype = datum->otype; + return SEPOL_EEXIST; + } + if (datum->otype == otype) + break; + last = datum; + datum = datum->next; + } + if (!datum) { + datum = malloc(sizeof(*datum)); + if (!datum) + return SEPOL_ENOMEM; + + ebitmap_init(&datum->stypes); + datum->otype = otype; + datum->next = NULL; + + if (last) { + last->next = datum; + } else { + char *name_dup; + + if (name_alloc) { + name_dup = *name_alloc; + *name_alloc = NULL; + } else { + name_dup = strdup(name); + if (!name_dup) { + free(datum); + return SEPOL_ENOMEM; + } + } + + ft = malloc(sizeof(*ft)); + if (!ft) { + free(name_dup); + free(datum); + return SEPOL_ENOMEM; + } + + ft->ttype = ttype; + ft->tclass = tclass; + ft->name = name_dup; + + if (hashtab_insert(p->filename_trans, (hashtab_key_t)ft, + (hashtab_datum_t)datum)) { + free(name_dup); + free(datum); + free(ft); + return SEPOL_ENOMEM; + } + } + } + + p->filename_trans_count++; + return ksu_ebitmap_set_bit(&datum->stypes, stype - 1, 1); +} + +static int filename_trans_read_one_compat(policydb_t *p, struct policy_file *fp) +{ + uint32_t buf[4], len, stype, ttype, tclass, otype; + char *name = NULL; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + return -1; + + name = calloc(len + 1, sizeof(*name)); + if (!name) + return -1; + + rc = next_entry(name, fp, len); + if (rc < 0) + goto err; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 4); + if (rc < 0) + goto err; + + stype = le32_to_cpu(buf[0]); + if (stype == 0) + goto err; + + ttype = le32_to_cpu(buf[1]); + tclass = le32_to_cpu(buf[2]); + otype = le32_to_cpu(buf[3]); + + rc = policydb_filetrans_insert(p, stype, ttype, tclass, name, &name, + otype, NULL); + if (rc) { + if (rc != SEPOL_EEXIST) + goto err; + /* + * Some old policies were wrongly generated with + * duplicate filename transition rules. For backward + * compatibility, do not reject such policies, just + * ignore the duplicate. + */ + } + free(name); + return 0; +err: + free(name); + return -1; +} + +static int filename_trans_check_datum(filename_trans_datum_t *datum) +{ + ebitmap_t stypes, otypes; + int rc = -1; + + ebitmap_init(&stypes); + ebitmap_init(&otypes); + + while (datum) { + if (ksu_ebitmap_get_bit(&otypes, datum->otype)) + goto out; + + if (ksu_ebitmap_set_bit(&otypes, datum->otype, 1)) + goto out; + + if (ebitmap_match_any(&stypes, &datum->stypes)) + goto out; + + if (ebitmap_union(&stypes, &datum->stypes)) + goto out; + + datum = datum->next; + } + rc = 0; +out: + ksu_ebitmap_destroy(&stypes); + ksu_ebitmap_destroy(&otypes); + return rc; +} + +static int filename_trans_read_one(policydb_t *p, struct policy_file *fp) +{ + filename_trans_key_t *ft = NULL; + filename_trans_datum_t **dst, *datum, *first = NULL; + unsigned int i; + uint32_t buf[3], len, ttype, tclass, ndatum; + char *name = NULL; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + return -1; + + name = calloc(len + 1, sizeof(*name)); + if (!name) + return -1; + + rc = next_entry(name, fp, len); + if (rc < 0) + goto err; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) + goto err; + + ttype = le32_to_cpu(buf[0]); + tclass = le32_to_cpu(buf[1]); + ndatum = le32_to_cpu(buf[2]); + if (ndatum == 0) + goto err; + + dst = &first; + for (i = 0; i < ndatum; i++) { + datum = malloc(sizeof(*datum)); + if (!datum) + goto err; + + datum->next = NULL; + *dst = datum; + + /* ksu_ebitmap_read() will at least init the bitmap */ + rc = ksu_ebitmap_read(&datum->stypes, fp); + if (rc < 0) + goto err; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto err; + + datum->otype = le32_to_cpu(buf[0]); + + p->filename_trans_count += ebitmap_cardinality(&datum->stypes); + + dst = &datum->next; + } + + if (ndatum > 1 && filename_trans_check_datum(first)) + goto err; + + ft = malloc(sizeof(*ft)); + if (!ft) + goto err; + + ft->ttype = ttype; + ft->tclass = tclass; + ft->name = name; + + rc = hashtab_insert(p->filename_trans, (hashtab_key_t)ft, + (hashtab_datum_t)first); + if (rc) + goto err; + + return 0; +err: + free(ft); + free(name); + while (first) { + datum = first; + first = first->next; + + ksu_ebitmap_destroy(&datum->stypes); + free(datum); + } + return -1; +} + +static int filename_trans_read(policydb_t *p, struct policy_file *fp) +{ + unsigned int i; + uint32_t buf[1], nel; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + + if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { + for (i = 0; i < nel; i++) { + rc = filename_trans_read_one_compat(p, fp); + if (rc < 0) + return -1; + } + } else { + for (i = 0; i < nel; i++) { + rc = filename_trans_read_one(p, fp); + if (rc < 0) + return -1; + } + } + return 0; +} + +static int ocontext_read_xen(const struct policydb_compat_info *info, + policydb_t *p, struct policy_file *fp) +{ + unsigned int i, j; + size_t nel, len; + ocontext_t *l, *c; + uint32_t buf[8]; + int rc; + + for (i = 0; i < info->ocon_num; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + l = NULL; + for (j = 0; j < nel; j++) { + c = calloc(1, sizeof(ocontext_t)); + if (!c) + return -1; + if (l) + l->next = c; + else + p->ocontexts[i] = c; + l = c; + switch (i) { + case OCON_XEN_ISID: + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + c->sid[0] = le32_to_cpu(buf[0]); + if (is_saturated(c->sid[0])) + return -1; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_XEN_PIRQ: + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + c->u.pirq = le32_to_cpu(buf[0]); + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_XEN_IOPORT: + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + c->u.ioport.low_ioport = le32_to_cpu(buf[0]); + c->u.ioport.high_ioport = le32_to_cpu(buf[1]); + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_XEN_IOMEM: + if (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) { + uint64_t b64[2]; + rc = next_entry(b64, fp, sizeof(uint64_t) * 2); + if (rc < 0) + return -1; + c->u.iomem.low_iomem = le64_to_cpu(b64[0]); + c->u.iomem.high_iomem = le64_to_cpu(b64[1]); + } else { + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + c->u.iomem.low_iomem = le32_to_cpu(buf[0]); + c->u.iomem.high_iomem = le32_to_cpu(buf[1]); + } + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_XEN_PCIDEVICE: + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + c->u.device = le32_to_cpu(buf[0]); + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_XEN_DEVICETREE: + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + return -1; + + c->u.name = malloc(len + 1); + if (!c->u.name) + return -1; + rc = next_entry(c->u.name, fp, len); + if (rc < 0) + return -1; + c->u.name[len] = 0; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + default: + /* should never get here */ + ERR(fp->handle, "Unknown Xen ocontext"); + return -1; + } + } + } + return 0; +} +static int ocontext_read_selinux(const struct policydb_compat_info *info, + policydb_t * p, struct policy_file *fp) +{ + unsigned int i, j; + size_t nel, len; + ocontext_t *l, *c; + uint32_t buf[8]; + int rc; + + for (i = 0; i < info->ocon_num; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + l = NULL; + for (j = 0; j < nel; j++) { + c = calloc(1, sizeof(ocontext_t)); + if (!c) { + return -1; + } + if (l) { + l->next = c; + } else { + p->ocontexts[i] = c; + } + l = c; + switch (i) { + case OCON_ISID: + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + c->sid[0] = le32_to_cpu(buf[0]); + if (is_saturated(c->sid[0])) + return -1; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_FS: + case OCON_NETIF: + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len) || len > 63) + return -1; + c->u.name = malloc(len + 1); + if (!c->u.name) + return -1; + rc = next_entry(c->u.name, fp, len); + if (rc < 0) + return -1; + c->u.name[len] = 0; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + if (context_read_and_validate + (&c->context[1], p, fp)) + return -1; + break; + case OCON_IBPKEY: { + uint32_t pkey_lo, pkey_hi; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 4); + if (rc < 0) + return -1; + + pkey_lo = le32_to_cpu(buf[2]); + pkey_hi = le32_to_cpu(buf[3]); + + if (pkey_lo > UINT16_MAX || pkey_hi > UINT16_MAX) + return -1; + + c->u.ibpkey.low_pkey = pkey_lo; + c->u.ibpkey.high_pkey = pkey_hi; + + /* we want c->u.ibpkey.subnet_prefix in network + * (big-endian) order, just memcpy it */ + memcpy(&c->u.ibpkey.subnet_prefix, buf, + sizeof(c->u.ibpkey.subnet_prefix)); + + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + } + case OCON_IBENDPORT: { + uint32_t port; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); + if (len == 0 || len > IB_DEVICE_NAME_MAX - 1) + return -1; + + port = le32_to_cpu(buf[1]); + if (port > UINT8_MAX || port == 0) + return -1; + + c->u.ibendport.dev_name = malloc(len + 1); + if (!c->u.ibendport.dev_name) + return -1; + rc = next_entry(c->u.ibendport.dev_name, fp, len); + if (rc < 0) + return -1; + c->u.ibendport.dev_name[len] = 0; + c->u.ibendport.port = port; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + } + case OCON_PORT: + rc = next_entry(buf, fp, sizeof(uint32_t) * 3); + if (rc < 0) + return -1; + c->u.port.protocol = le32_to_cpu(buf[0]); + c->u.port.low_port = le32_to_cpu(buf[1]); + c->u.port.high_port = le32_to_cpu(buf[2]); + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_NODE: + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + c->u.node.addr = buf[0]; /* network order */ + c->u.node.mask = buf[1]; /* network order */ + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_FSUSE: + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + c->v.behavior = le32_to_cpu(buf[0]); + len = le32_to_cpu(buf[1]); + if (zero_or_saturated(len)) + return -1; + c->u.name = malloc(len + 1); + if (!c->u.name) + return -1; + rc = next_entry(c->u.name, fp, len); + if (rc < 0) + return -1; + c->u.name[len] = 0; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_NODE6:{ + int k; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 8); + if (rc < 0) + return -1; + for (k = 0; k < 4; k++) + /* network order */ + c->u.node6.addr[k] = buf[k]; + for (k = 0; k < 4; k++) + /* network order */ + c->u.node6.mask[k] = buf[k + 4]; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + } + default:{ + ERR(fp->handle, "Unknown SELinux ocontext"); + return -1; + } + } + } + } + return 0; +} + +static int ocontext_read(const struct policydb_compat_info *info, + policydb_t *p, struct policy_file *fp) +{ + int rc = -1; + switch (p->target_platform) { + case SEPOL_TARGET_SELINUX: + rc = ocontext_read_selinux(info, p, fp); + break; + case SEPOL_TARGET_XEN: + rc = ocontext_read_xen(info, p, fp); + break; + default: + ERR(fp->handle, "Unknown target"); + } + return rc; +} + +static int genfs_read(policydb_t * p, struct policy_file *fp) +{ + uint32_t buf[1]; + size_t nel, nel2, len, len2; + genfs_t *genfs_p, *newgenfs, *genfs; + size_t i, j; + ocontext_t *l, *c, *newc = NULL; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + nel = le32_to_cpu(buf[0]); + genfs_p = NULL; + for (i = 0; i < nel; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + newgenfs = calloc(1, sizeof(genfs_t)); + if (!newgenfs) + goto bad; + newgenfs->fstype = malloc(len + 1); + if (!newgenfs->fstype) { + free(newgenfs); + goto bad; + } + rc = next_entry(newgenfs->fstype, fp, len); + if (rc < 0) { + free(newgenfs->fstype); + free(newgenfs); + goto bad; + } + newgenfs->fstype[len] = 0; + for (genfs_p = NULL, genfs = p->genfs; genfs; + genfs_p = genfs, genfs = genfs->next) { + if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { + ERR(fp->handle, "dup genfs fstype %s", + newgenfs->fstype); + free(newgenfs->fstype); + free(newgenfs); + goto bad; + } + if (strcmp(newgenfs->fstype, genfs->fstype) < 0) + break; + } + newgenfs->next = genfs; + if (genfs_p) + genfs_p->next = newgenfs; + else + p->genfs = newgenfs; + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + nel2 = le32_to_cpu(buf[0]); + for (j = 0; j < nel2; j++) { + newc = calloc(1, sizeof(ocontext_t)); + if (!newc) { + goto bad; + } + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + newc->u.name = malloc(len + 1); + if (!newc->u.name) { + goto bad; + } + rc = next_entry(newc->u.name, fp, len); + if (rc < 0) + goto bad; + newc->u.name[len] = 0; + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + newc->v.sclass = le32_to_cpu(buf[0]); + if (context_read_and_validate(&newc->context[0], p, fp)) + goto bad; + for (l = NULL, c = newgenfs->head; c; + l = c, c = c->next) { + if (!strcmp(newc->u.name, c->u.name) && + (!c->v.sclass || !newc->v.sclass || + newc->v.sclass == c->v.sclass)) { + ERR(fp->handle, "dup genfs entry " + "(%s,%s)", newgenfs->fstype, + c->u.name); + goto bad; + } + len = strlen(newc->u.name); + len2 = strlen(c->u.name); + if (len > len2) + break; + } + newc->next = c; + if (l) + l->next = newc; + else + newgenfs->head = newc; + /* clear newc after a new owner has the pointer */ + newc = NULL; + } + } + + return 0; + + bad: + if (newc) { + context_destroy(&newc->context[0]); + context_destroy(&newc->context[1]); + free(newc->u.name); + free(newc); + } + return -1; +} + +/* + * Read a MLS level structure from a policydb binary + * representation file. + */ +static int mls_read_level(mls_level_t * lp, struct policy_file *fp) +{ + uint32_t buf[1]; + int rc; + + mls_level_init(lp); + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) { + ERR(fp->handle, "truncated level"); + goto bad; + } + lp->sens = le32_to_cpu(buf[0]); + + if (ksu_ebitmap_read(&lp->cat, fp)) { + ERR(fp->handle, "error reading level categories"); + goto bad; + } + return 0; + + bad: + return -EINVAL; +} + +static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp) +{ + char *key = 0; + user_datum_t *usrdatum; + uint32_t buf[3]; + size_t len; + int rc, to_read = 2; + + usrdatum = calloc(1, sizeof(user_datum_t)); + if (!usrdatum) + return -1; + + if (policydb_has_boundary_feature(p)) + to_read = 3; + + rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + + usrdatum->s.value = le32_to_cpu(buf[1]); + if (policydb_has_boundary_feature(p)) + usrdatum->bounds = le32_to_cpu(buf[2]); + + key = malloc(len + 1); + if (!key) + goto bad; + rc = next_entry(key, fp, len); + if (rc < 0) + goto bad; + key[len] = 0; + + if (p->policy_type == POLICY_KERN) { + if (ksu_ebitmap_read(&usrdatum->roles.roles, fp)) + goto bad; + } else { + if (role_set_read(&usrdatum->roles, fp)) + goto bad; + } + + /* users were not allowed in mls modules before version + * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been + * required - the mls fields will be empty. user declarations in + * non-mls modules will also have empty mls fields */ + if ((p->policy_type == POLICY_KERN + && p->policyvers >= POLICYDB_VERSION_MLS) + || (p->policy_type == POLICY_MOD + && p->policyvers >= MOD_POLICYDB_VERSION_MLS + && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS) + || (p->policy_type == POLICY_BASE + && p->policyvers >= MOD_POLICYDB_VERSION_MLS + && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) { + if (mls_read_range_helper(&usrdatum->exp_range, fp)) + goto bad; + if (mls_read_level(&usrdatum->exp_dfltlevel, fp)) + goto bad; + if (p->policy_type != POLICY_KERN) { + if (mls_range_to_semantic(&usrdatum->exp_range, + &usrdatum->range)) + goto bad; + if (mls_level_to_semantic(&usrdatum->exp_dfltlevel, + &usrdatum->dfltlevel)) + goto bad; + } + } else if ((p->policy_type == POLICY_MOD + && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS) + || (p->policy_type == POLICY_BASE + && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) { + if (mls_read_semantic_range_helper(&usrdatum->range, fp)) + goto bad; + if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp)) + goto bad; + } + + if (hashtab_insert(h, key, usrdatum)) + goto bad; + + return 0; + + bad: + user_destroy(key, usrdatum, NULL); + return -1; +} + +static int sens_read(policydb_t * p + __attribute__ ((unused)), hashtab_t h, + struct policy_file *fp) +{ + char *key = 0; + level_datum_t *levdatum; + uint32_t buf[2], len; + int rc; + + levdatum = malloc(sizeof(level_datum_t)); + if (!levdatum) + return -1; + level_datum_init(levdatum); + + rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + + levdatum->isalias = le32_to_cpu(buf[1]); + + key = malloc(len + 1); + if (!key) + goto bad; + rc = next_entry(key, fp, len); + if (rc < 0) + goto bad; + key[len] = 0; + + levdatum->level = malloc(sizeof(mls_level_t)); + if (!levdatum->level || mls_read_level(levdatum->level, fp)) + goto bad; + + if (hashtab_insert(h, key, levdatum)) + goto bad; + + return 0; + + bad: + sens_destroy(key, levdatum, NULL); + return -1; +} + +static int cat_read(policydb_t * p + __attribute__ ((unused)), hashtab_t h, + struct policy_file *fp) +{ + char *key = 0; + cat_datum_t *catdatum; + uint32_t buf[3], len; + int rc; + + catdatum = malloc(sizeof(cat_datum_t)); + if (!catdatum) + return -1; + cat_datum_init(catdatum); + + rc = next_entry(buf, fp, (sizeof(uint32_t) * 3)); + if (rc < 0) + goto bad; + + len = le32_to_cpu(buf[0]); + if(zero_or_saturated(len)) + goto bad; + + catdatum->s.value = le32_to_cpu(buf[1]); + catdatum->isalias = le32_to_cpu(buf[2]); + + key = malloc(len + 1); + if (!key) + goto bad; + rc = next_entry(key, fp, len); + if (rc < 0) + goto bad; + key[len] = 0; + + if (hashtab_insert(h, key, catdatum)) + goto bad; + + return 0; + + bad: + cat_destroy(key, catdatum, NULL); + return -1; +} + +static int (*read_f[SYM_NUM]) (policydb_t * p, hashtab_t h, + struct policy_file * fp) = { +common_read, class_read, role_read, type_read, user_read, + ksu_cond_read_bool, sens_read, cat_read,}; + +/************** module reading functions below **************/ + +static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp) +{ + unsigned int i; + uint32_t buf[2], len; + class_perm_node_t *cur, *tail = NULL; + avrule_t *avrule; + int rc; + + avrule = (avrule_t *) malloc(sizeof(avrule_t)); + if (!avrule) + return NULL; + + avrule_init(avrule); + + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + goto bad; + + avrule->specified = le32_to_cpu(buf[0]); + avrule->flags = le32_to_cpu(buf[1]); + + if (type_set_read(&avrule->stypes, fp)) + goto bad; + + if (type_set_read(&avrule->ttypes, fp)) + goto bad; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto bad; + len = le32_to_cpu(buf[0]); + + for (i = 0; i < len; i++) { + cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); + if (!cur) + goto bad; + class_perm_node_init(cur); + + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) { + free(cur); + goto bad; + } + + cur->tclass = le32_to_cpu(buf[0]); + cur->data = le32_to_cpu(buf[1]); + + if (!tail) { + avrule->perms = cur; + } else { + tail->next = cur; + } + tail = cur; + } + + if (avrule->specified & AVRULE_XPERMS) { + uint8_t buf8; + size_t nel = ARRAY_SIZE(avrule->xperms->perms); + uint32_t buf32[nel]; + + if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { + ERR(fp->handle, + "module policy version %u does not support ioctl" + " extended permissions rules and one was specified", + p->policyvers); + goto bad; + } + + if (p->target_platform != SEPOL_TARGET_SELINUX) { + ERR(fp->handle, + "Target platform %s does not support ioctl" + " extended permissions rules and one was specified", + policydb_target_strings[p->target_platform]); + goto bad; + } + + avrule->xperms = calloc(1, sizeof(*avrule->xperms)); + if (!avrule->xperms) + goto bad; + + rc = next_entry(&buf8, fp, sizeof(uint8_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + goto bad; + } + avrule->xperms->specified = buf8; + rc = next_entry(&buf8, fp, sizeof(uint8_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + goto bad; + } + avrule->xperms->driver = buf8; + rc = next_entry(buf32, fp, sizeof(uint32_t)*nel); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + goto bad; + } + for (i = 0; i < nel; i++) + avrule->xperms->perms[i] = le32_to_cpu(buf32[i]); + } + + return avrule; + bad: + if (avrule) { + avrule_destroy(avrule); + free(avrule); + } + return NULL; +} + +static int range_read(policydb_t * p, struct policy_file *fp) +{ + uint32_t buf[2], nel; + range_trans_t *rt = NULL; + struct mls_range *r = NULL; + range_trans_rule_t *rtr = NULL, *lrtr = NULL; + unsigned int i; + int new_rangetr = (p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_RANGETRANS); + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + for (i = 0; i < nel; i++) { + rt = calloc(1, sizeof(range_trans_t)); + if (!rt) + return -1; + rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); + if (rc < 0) + goto err; + rt->source_type = le32_to_cpu(buf[0]); + if (!value_isvalid(rt->source_type, p->p_types.nprim)) + goto err; + rt->target_type = le32_to_cpu(buf[1]); + if (!value_isvalid(rt->target_type, p->p_types.nprim)) + goto err; + if (new_rangetr) { + rc = next_entry(buf, fp, (sizeof(uint32_t))); + if (rc < 0) + goto err; + rt->target_class = le32_to_cpu(buf[0]); + if (!value_isvalid(rt->target_class, p->p_classes.nprim)) + goto err; + } else + rt->target_class = p->process_class; + r = calloc(1, sizeof(*r)); + if (!r) + goto err; + if (mls_read_range_helper(r, fp)) + goto err; + + if (p->policy_type == POLICY_KERN) { + rc = hashtab_insert(p->range_tr, (hashtab_key_t)rt, r); + if (rc) + goto err; + rt = NULL; + r = NULL; + continue; + } + + /* Module policy: convert to range_trans_rule and discard. */ + rtr = malloc(sizeof(range_trans_rule_t)); + if (!rtr) + goto err; + range_trans_rule_init(rtr); + + if (ksu_ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1)) + goto err; + + if (ksu_ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1)) + goto err; + + if (ksu_ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1)) + goto err; + + if (mls_range_to_semantic(r, &rtr->trange)) + goto err; + + if (lrtr) + lrtr->next = rtr; + else + p->global->enabled->range_tr_rules = rtr; + + free(rt); + rt = NULL; + free(r); + r = NULL; + lrtr = rtr; + } + + return 0; +err: + free(rt); + if (r) { + mls_range_destroy(r); + free(r); + } + if (rtr) { + range_trans_rule_destroy(rtr); + free(rtr); + } + return -1; +} + +int avrule_read_list(policydb_t * p, avrule_t ** avrules, + struct policy_file *fp) +{ + unsigned int i; + avrule_t *cur, *tail; + uint32_t buf[1], len; + int rc; + + *avrules = tail = NULL; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) { + return -1; + } + len = le32_to_cpu(buf[0]); + + for (i = 0; i < len; i++) { + cur = avrule_read(p, fp); + if (!cur) { + return -1; + } + + if (!tail) { + *avrules = cur; + } else { + tail->next = cur; + } + tail = cur; + } + + return 0; +} + +static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r, + struct policy_file *fp) +{ + uint32_t buf[1], nel; + unsigned int i; + role_trans_rule_t *tr, *ltr; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + ltr = NULL; + for (i = 0; i < nel; i++) { + tr = malloc(sizeof(role_trans_rule_t)); + if (!tr) { + return -1; + } + role_trans_rule_init(tr); + + if (ltr) { + ltr->next = tr; + } else { + *r = tr; + } + + if (role_set_read(&tr->roles, fp)) + return -1; + + if (type_set_read(&tr->types, fp)) + return -1; + + if (p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS) { + if (ksu_ebitmap_read(&tr->classes, fp)) + return -1; + } else { + if (!p->process_class) + return -1; + if (ksu_ebitmap_set_bit(&tr->classes, p->process_class - 1, 1)) + return -1; + } + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + tr->new_role = le32_to_cpu(buf[0]); + ltr = tr; + } + + return 0; +} + +static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp) +{ + unsigned int i; + uint32_t buf[1], nel; + role_allow_rule_t *ra, *lra; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + lra = NULL; + for (i = 0; i < nel; i++) { + ra = malloc(sizeof(role_allow_rule_t)); + if (!ra) { + return -1; + } + role_allow_rule_init(ra); + + if (lra) { + lra->next = ra; + } else { + *r = ra; + } + + if (role_set_read(&ra->roles, fp)) + return -1; + + if (role_set_read(&ra->new_roles, fp)) + return -1; + + lra = ra; + } + return 0; +} + +static int filename_trans_rule_read(policydb_t *p, filename_trans_rule_t **r, + struct policy_file *fp) +{ + uint32_t buf[3], nel, i, len; + unsigned int entries; + filename_trans_rule_t *ftr, *lftr; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + lftr = NULL; + for (i = 0; i < nel; i++) { + ftr = malloc(sizeof(*ftr)); + if (!ftr) + return -1; + + filename_trans_rule_init(ftr); + + if (lftr) + lftr->next = ftr; + else + *r = ftr; + lftr = ftr; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + return -1; + + ftr->name = malloc(len + 1); + if (!ftr->name) + return -1; + + rc = next_entry(ftr->name, fp, len); + if (rc) + return -1; + ftr->name[len] = 0; + + if (type_set_read(&ftr->stypes, fp)) + return -1; + + if (type_set_read(&ftr->ttypes, fp)) + return -1; + + if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS) + entries = 3; + else + entries = 2; + + rc = next_entry(buf, fp, sizeof(uint32_t) * entries); + if (rc < 0) + return -1; + ftr->tclass = le32_to_cpu(buf[0]); + ftr->otype = le32_to_cpu(buf[1]); + if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS) + ftr->flags = le32_to_cpu(buf[2]); + } + + return 0; +} + +static int range_trans_rule_read(range_trans_rule_t ** r, + struct policy_file *fp) +{ + uint32_t buf[1], nel; + unsigned int i; + range_trans_rule_t *rt, *lrt = NULL; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf[0]); + for (i = 0; i < nel; i++) { + rt = malloc(sizeof(range_trans_rule_t)); + if (!rt) { + return -1; + } + range_trans_rule_init(rt); + + if (lrt) + lrt->next = rt; + else + *r = rt; + + if (type_set_read(&rt->stypes, fp)) + return -1; + + if (type_set_read(&rt->ttypes, fp)) + return -1; + + if (ksu_ebitmap_read(&rt->tclasses, fp)) + return -1; + + if (mls_read_semantic_range_helper(&rt->trange, fp)) + return -1; + + lrt = rt; + } + + return 0; +} + +static int scope_index_read(scope_index_t * scope_index, + unsigned int num_scope_syms, struct policy_file *fp) +{ + unsigned int i; + uint32_t buf[1]; + int rc; + + for (i = 0; i < num_scope_syms; i++) { + if (ksu_ebitmap_read(scope_index->scope + i, fp) < 0) { + return -1; + } + } + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + scope_index->class_perms_len = le32_to_cpu(buf[0]); + if (is_saturated(scope_index->class_perms_len)) + return -1; + if (scope_index->class_perms_len == 0) { + scope_index->class_perms_map = NULL; + return 0; + } + if ((scope_index->class_perms_map = + calloc(scope_index->class_perms_len, + sizeof(*scope_index->class_perms_map))) == NULL) { + return -1; + } + for (i = 0; i < scope_index->class_perms_len; i++) { + if (ksu_ebitmap_read(scope_index->class_perms_map + i, fp) < 0) { + return -1; + } + } + return 0; +} + +static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl, + unsigned int num_scope_syms, struct policy_file *fp) +{ + uint32_t buf[2], nprim, nel; + unsigned int i, j; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + decl->decl_id = le32_to_cpu(buf[0]); + decl->enabled = le32_to_cpu(buf[1]); + if (ksu_cond_read_list(p, &decl->cond_list, fp) == -1 || + avrule_read_list(p, &decl->avrules, fp) == -1 || + role_trans_rule_read(p, &decl->role_tr_rules, fp) == -1 || + role_allow_rule_read(&decl->role_allow_rules, fp) == -1) { + return -1; + } + + if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS && + filename_trans_rule_read(p, &decl->filename_trans_rules, fp)) + return -1; + + if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS && + range_trans_rule_read(&decl->range_tr_rules, fp) == -1) { + return -1; + } + if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 || + scope_index_read(&decl->declared, num_scope_syms, fp) == -1) { + return -1; + } + + for (i = 0; i < num_scope_syms; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + nprim = le32_to_cpu(buf[0]); + if (is_saturated(nprim)) + return -1; + nel = le32_to_cpu(buf[1]); + for (j = 0; j < nel; j++) { + if (read_f[i] (p, decl->symtab[i].table, fp)) { + return -1; + } + } + decl->symtab[i].nprim = nprim; + } + return 0; +} + +static int avrule_block_read(policydb_t * p, + avrule_block_t ** block, + unsigned int num_scope_syms, + struct policy_file *fp) +{ + avrule_block_t *last_block = NULL, *curblock; + uint32_t buf[1], num_blocks, nel; + int rc; + + assert(*block == NULL); + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + num_blocks = le32_to_cpu(buf[0]); + nel = num_blocks; + while (num_blocks > 0) { + avrule_decl_t *last_decl = NULL, *curdecl; + uint32_t num_decls; + if ((curblock = calloc(1, sizeof(*curblock))) == NULL) { + return -1; + } + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) { + free(curblock); + return -1; + } + /* if this is the first block its non-optional, else its optional */ + if (num_blocks != nel) + curblock->flags |= AVRULE_OPTIONAL; + + num_decls = le32_to_cpu(buf[0]); + while (num_decls > 0) { + if ((curdecl = avrule_decl_create(0)) == NULL) { + avrule_block_destroy(curblock); + return -1; + } + if (avrule_decl_read(p, curdecl, num_scope_syms, fp) == + -1) { + avrule_decl_destroy(curdecl); + avrule_block_destroy(curblock); + return -1; + } + if (curdecl->enabled) { + if (curblock->enabled != NULL) { + /* probably a corrupt file */ + avrule_decl_destroy(curdecl); + avrule_block_destroy(curblock); + return -1; + } + curblock->enabled = curdecl; + } + /* one must be careful to reconstruct the + * decl chain in its correct order */ + if (curblock->branch_list == NULL) { + curblock->branch_list = curdecl; + } else { + assert(last_decl); + last_decl->next = curdecl; + } + last_decl = curdecl; + num_decls--; + } + + if (*block == NULL) { + *block = curblock; + } else { + assert(last_block); + last_block->next = curblock; + } + last_block = curblock; + + num_blocks--; + } + + return 0; +} + +static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) +{ + scope_datum_t *scope = NULL; + uint32_t buf[2]; + char *key = NULL; + size_t key_len; + unsigned int i; + hashtab_t h = p->scope[symnum].table; + int rc; + + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto cleanup; + key_len = le32_to_cpu(buf[0]); + if (zero_or_saturated(key_len)) + goto cleanup; + key = malloc(key_len + 1); + if (!key) + goto cleanup; + rc = next_entry(key, fp, key_len); + if (rc < 0) + goto cleanup; + key[key_len] = '\0'; + + /* ensure that there already exists a symbol with this key */ + if (hashtab_search(p->symtab[symnum].table, key) == NULL) { + goto cleanup; + } + + if ((scope = calloc(1, sizeof(*scope))) == NULL) { + goto cleanup; + } + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + goto cleanup; + scope->scope = le32_to_cpu(buf[0]); + scope->decl_ids_len = le32_to_cpu(buf[1]); + if (zero_or_saturated(scope->decl_ids_len)) { + ERR(fp->handle, "invalid scope with no declaration"); + goto cleanup; + } + if ((scope->decl_ids = + calloc(scope->decl_ids_len, sizeof(uint32_t))) == NULL) { + goto cleanup; + } + rc = next_entry(scope->decl_ids, fp, sizeof(uint32_t) * scope->decl_ids_len); + if (rc < 0) + goto cleanup; + for (i = 0; i < scope->decl_ids_len; i++) { + scope->decl_ids[i] = le32_to_cpu(scope->decl_ids[i]); + } + + if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) { + /* object_r was already added to this table in roles_init() */ + scope_destroy(key, scope, NULL); + } else { + if (hashtab_insert(h, key, scope)) { + goto cleanup; + } + } + + return 0; + + cleanup: + scope_destroy(key, scope, NULL); + return -1; +} + +static sepol_security_class_t policydb_string_to_security_class( + struct policydb *policydb, + const char *class_name) +{ + class_datum_t *tclass_datum; + + tclass_datum = hashtab_search(policydb->p_classes.table, + class_name); + if (!tclass_datum) + return 0; + return tclass_datum->s.value; +} + +static sepol_access_vector_t policydb_string_to_av_perm( + struct policydb *policydb, + sepol_security_class_t tclass, + const char *perm_name) +{ + class_datum_t *tclass_datum; + perm_datum_t *perm_datum; + + if (!tclass || tclass > policydb->p_classes.nprim) + return 0; + tclass_datum = policydb->class_val_to_struct[tclass - 1]; + + perm_datum = (perm_datum_t *) + hashtab_search(tclass_datum->permissions.table, + perm_name); + if (perm_datum != NULL) + return UINT32_C(1) << (perm_datum->s.value - 1); + + if (tclass_datum->comdatum == NULL) + return 0; + + perm_datum = (perm_datum_t *) + hashtab_search(tclass_datum->comdatum->permissions.table, + perm_name); + + if (perm_datum != NULL) + return UINT32_C(1) << (perm_datum->s.value - 1); + + return 0; +} + + +/* + * Read the configuration data from a policy database binary + * representation file into a policy database structure. + */ +int ksu_policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) +{ + + unsigned int i, j, r_policyvers; + uint32_t buf[5]; + size_t len, nprim, nel; + char *policydb_str; + const struct policydb_compat_info *info; + unsigned int policy_type, bufindex; + ebitmap_node_t *tnode; + int rc; + + /* Read the magic number and string length. */ + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return POLICYDB_ERROR; + for (i = 0; i < 2; i++) + buf[i] = le32_to_cpu(buf[i]); + + if (buf[0] == POLICYDB_MAGIC) { + policy_type = POLICY_KERN; + } else if (buf[0] == POLICYDB_MOD_MAGIC) { + policy_type = POLICY_MOD; + } else { + ERR(fp->handle, "policydb magic number %#08x does not " + "match expected magic number %#08x or %#08x", + buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC); + return POLICYDB_ERROR; + } + + len = buf[1]; + if (len == 0 || len > POLICYDB_STRING_MAX_LENGTH) { + ERR(fp->handle, "policydb string length %s ", len ? "too long" : "zero"); + return POLICYDB_ERROR; + } + + policydb_str = malloc(len + 1); + if (!policydb_str) { + ERR(fp->handle, "unable to allocate memory for policydb " + "string of length %zu", len); + return POLICYDB_ERROR; + } + rc = next_entry(policydb_str, fp, len); + if (rc < 0) { + ERR(fp->handle, "truncated policydb string identifier"); + free(policydb_str); + return POLICYDB_ERROR; + } + policydb_str[len] = 0; + + if (policy_type == POLICY_KERN) { + for (i = 0; i < POLICYDB_TARGET_SZ; i++) { + if ((strcmp(policydb_str, policydb_target_strings[i]) + == 0)) { + policydb_set_target_platform(p, i); + break; + } + } + + if (i == POLICYDB_TARGET_SZ) { + ERR(fp->handle, "cannot find a valid target for policy " + "string %s", policydb_str); + free(policydb_str); + return POLICYDB_ERROR; + } + } else { + if (strcmp(policydb_str, POLICYDB_MOD_STRING)) { + ERR(fp->handle, "invalid string identifier %s", + policydb_str); + free(policydb_str); + return POLICYDB_ERROR; + } + } + + /* Done with policydb_str. */ + free(policydb_str); + policydb_str = NULL; + + /* Read the version, config, and table sizes (and policy type if it's a module). */ + if (policy_type == POLICY_KERN) + nel = 4; + else + nel = 5; + + rc = next_entry(buf, fp, sizeof(uint32_t) * nel); + if (rc < 0) + return POLICYDB_ERROR; + for (i = 0; i < nel; i++) + buf[i] = le32_to_cpu(buf[i]); + + bufindex = 0; + + if (policy_type == POLICY_MOD) { + /* We know it's a module but not whether it's a base + module or regular binary policy module. buf[0] + tells us which. */ + policy_type = buf[bufindex]; + if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) { + ERR(fp->handle, "unknown module type: %#08x", + policy_type); + return POLICYDB_ERROR; + } + bufindex++; + } + + r_policyvers = buf[bufindex]; + if (policy_type == POLICY_KERN) { + if (r_policyvers < POLICYDB_VERSION_MIN || + r_policyvers > POLICYDB_VERSION_MAX) { + ERR(fp->handle, "policydb version %d does not match " + "my version range %d-%d", buf[bufindex], + POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); + return POLICYDB_ERROR; + } + } else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) { + if (r_policyvers < MOD_POLICYDB_VERSION_MIN || + r_policyvers > MOD_POLICYDB_VERSION_MAX) { + ERR(fp->handle, "policydb module version %d does " + "not match my version range %d-%d", + buf[bufindex], MOD_POLICYDB_VERSION_MIN, + MOD_POLICYDB_VERSION_MAX); + return POLICYDB_ERROR; + } + } else { + assert(0); + } + bufindex++; + + /* Set the policy type and version from the read values. */ + p->policy_type = policy_type; + p->policyvers = r_policyvers; + + if (buf[bufindex] & POLICYDB_CONFIG_MLS) { + p->mls = 1; + } else { + p->mls = 0; + } + + p->handle_unknown = buf[bufindex] & POLICYDB_CONFIG_UNKNOWN_MASK; + + bufindex++; + + info = policydb_lookup_compat(r_policyvers, policy_type, + p->target_platform); + if (!info) { + ERR(fp->handle, "unable to find policy compat info " + "for version %d", r_policyvers); + goto bad; + } + + if (buf[bufindex] != info->sym_num + || buf[bufindex + 1] != info->ocon_num) { + ERR(fp->handle, + "policydb table sizes (%d,%d) do not " "match mine (%d,%d)", + buf[bufindex], buf[bufindex + 1], info->sym_num, + info->ocon_num); + goto bad; + } + + if (p->policy_type == POLICY_MOD) { + /* Get the module name and version */ + if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { + goto bad; + } + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + if ((p->name = malloc(len + 1)) == NULL) { + goto bad; + } + if ((rc = next_entry(p->name, fp, len)) < 0) { + goto bad; + } + p->name[len] = '\0'; + if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { + goto bad; + } + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto bad; + if ((p->version = malloc(len + 1)) == NULL) { + goto bad; + } + if ((rc = next_entry(p->version, fp, len)) < 0) { + goto bad; + } + p->version[len] = '\0'; + } + + if ((p->policyvers >= POLICYDB_VERSION_POLCAP && + p->policy_type == POLICY_KERN) || + (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && + p->policy_type == POLICY_BASE) || + (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && + p->policy_type == POLICY_MOD)) { + if (ksu_ebitmap_read(&p->policycaps, fp)) + goto bad; + } + + if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && + p->policy_type == POLICY_KERN) { + if (ksu_ebitmap_read(&p->permissive_map, fp)) + goto bad; + } + + for (i = 0; i < info->sym_num; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + goto bad; + nprim = le32_to_cpu(buf[0]); + if (is_saturated(nprim)) + goto bad; + nel = le32_to_cpu(buf[1]); + if (nel && !nprim) { + ERR(fp->handle, "unexpected items in symbol table with no symbol"); + goto bad; + } + for (j = 0; j < nel; j++) { + if (read_f[i] (p, p->symtab[i].table, fp)) + goto bad; + } + + p->symtab[i].nprim = nprim; + } + + switch (p->target_platform) { + case SEPOL_TARGET_SELINUX: + p->process_class = policydb_string_to_security_class(p, "process"); + p->dir_class = policydb_string_to_security_class(p, "dir"); + break; + case SEPOL_TARGET_XEN: + p->process_class = policydb_string_to_security_class(p, "domain"); + break; + default: + break; + } + + if (policy_type == POLICY_KERN) { + if (ksu_avtab_read(&p->te_avtab, fp, r_policyvers)) + goto bad; + if (r_policyvers >= POLICYDB_VERSION_BOOL) + if (ksu_cond_read_list(p, &p->cond_list, fp)) + goto bad; + if (role_trans_read(p, fp)) + goto bad; + if (role_allow_read(&p->role_allow, fp)) + goto bad; + if (r_policyvers >= POLICYDB_VERSION_FILENAME_TRANS && + filename_trans_read(p, fp)) + goto bad; + } else { + /* first read the AV rule blocks, then the scope tables */ + avrule_block_destroy(p->global); + p->global = NULL; + if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) { + goto bad; + } + if (p->global == NULL) { + ERR(fp->handle, "no avrule block in policy"); + goto bad; + } + for (i = 0; i < info->sym_num; i++) { + if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { + goto bad; + } + nel = le32_to_cpu(buf[0]); + for (j = 0; j < nel; j++) { + if (scope_read(p, i, fp)) + goto bad; + } + } + + } + + if (policydb_index_decls(fp->handle, p)) + goto bad; + + if (policydb_index_classes(p)) + goto bad; + + switch (p->target_platform) { + case SEPOL_TARGET_SELINUX: + /* fall through */ + case SEPOL_TARGET_XEN: + p->process_trans = policydb_string_to_av_perm(p, p->process_class, + "transition"); + p->process_trans_dyntrans = p->process_trans | + policydb_string_to_av_perm(p, p->process_class, + "dyntransition"); + break; + default: + break; + } + + if (policydb_index_others(fp->handle, p, verbose)) + goto bad; + + if (ocontext_read(info, p, fp) == -1) { + goto bad; + } + + if (genfs_read(p, fp) == -1) { + goto bad; + } + + if ((p->policy_type == POLICY_KERN + && p->policyvers >= POLICYDB_VERSION_MLS) + || (p->policy_type == POLICY_BASE + && p->policyvers >= MOD_POLICYDB_VERSION_MLS + && p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) { + if (range_read(p, fp)) { + goto bad; + } + } + + if (policy_type == POLICY_KERN) { + p->type_attr_map = calloc(p->p_types.nprim, sizeof(ebitmap_t)); + p->attr_type_map = calloc(p->p_types.nprim, sizeof(ebitmap_t)); + if (!p->type_attr_map || !p->attr_type_map) + goto bad; + for (i = 0; i < p->p_types.nprim; i++) { + if (r_policyvers >= POLICYDB_VERSION_AVTAB) { + if (ksu_ebitmap_read(&p->type_attr_map[i], fp)) + goto bad; + ebitmap_for_each_positive_bit(&p->type_attr_map[i], + tnode, j) { + if (i == j) + continue; + + if (j >= p->p_types.nprim) + goto bad; + + if (ksu_ebitmap_set_bit + (&p->attr_type_map[j], i, 1)) + goto bad; + } + } + /* add the type itself as the degenerate case */ + if (ksu_ebitmap_set_bit(&p->type_attr_map[i], i, 1)) + goto bad; + if (p->type_val_to_struct[i] && p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { + if (ksu_ebitmap_set_bit(&p->attr_type_map[i], i, 1)) + goto bad; + } + } + } + + if (validate_policydb(fp->handle, p)) + goto bad; + + return POLICYDB_SUCCESS; + bad: + return POLICYDB_ERROR; +} + +int policydb_reindex_users(policydb_t * p) +{ + unsigned int i = SYM_USERS; + + if (p->user_val_to_struct) + free(p->user_val_to_struct); + if (p->sym_val_to_name[i]) + free(p->sym_val_to_name[i]); + + p->user_val_to_struct = (user_datum_t **) + calloc(p->p_users.nprim, sizeof(user_datum_t *)); + if (!p->user_val_to_struct) + return -1; + + p->sym_val_to_name[i] = (char **) + calloc(p->symtab[i].nprim, sizeof(char *)); + if (!p->sym_val_to_name[i]) + return -1; + + if (ksu_hashtab_map(p->symtab[i].table, index_f[i], p)) + return -1; + + /* Expand user roles for context validity checking */ + if (ksu_hashtab_map(p->p_users.table, policydb_user_cache, p)) + return -1; + + return 0; +} + +void policy_file_init(policy_file_t *pf) +{ + memset(pf, 0, sizeof(policy_file_t)); +} + +int policydb_set_target_platform(policydb_t *p, int platform) +{ + if (platform == SEPOL_TARGET_SELINUX) + p->target_platform = SEPOL_TARGET_SELINUX; + else if (platform == SEPOL_TARGET_XEN) + p->target_platform = SEPOL_TARGET_XEN; + else + return -1; + + return 0; +} + +// int policydb_sort_ocontexts(policydb_t *p) +// { +// return sort_ocontexts(p); +// } diff --git a/kernel/libsepol/src/policydb.o b/kernel/libsepol/src/policydb.o new file mode 100644 index 00000000..7ad88ca6 Binary files /dev/null and b/kernel/libsepol/src/policydb.o differ diff --git a/kernel/libsepol/src/policydb_convert.c b/kernel/libsepol/src/policydb_convert.c new file mode 100644 index 00000000..7ee88f2a --- /dev/null +++ b/kernel/libsepol/src/policydb_convert.c @@ -0,0 +1,101 @@ +// #include + +#include "private.h" +#include "debug.h" + +#include + +/* Construct a policydb from the supplied (data, len) pair */ + +int policydb_from_image(sepol_handle_t * handle, + void *data, size_t len, policydb_t * policydb) +{ + + policy_file_t pf; + + policy_file_init(&pf); + pf.type = PF_USE_MEMORY; + pf.data = data; + pf.len = len; + pf.handle = handle; + + if (ksu_policydb_read(policydb, &pf, 0)) { + ksu_policydb_destroy(policydb); + ERR(handle, "policy image is invalid"); + // errno = EINVAL; + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +/* Write a policydb to a memory region, and return the (data, len) pair. */ + +int policydb_to_image(sepol_handle_t * handle, + policydb_t * policydb, void **newdata, size_t * newlen) +{ + + void *tmp_data = NULL; + size_t tmp_len; + policy_file_t pf; + struct policydb tmp_policydb; + + /* Compute the length for the new policy image. */ + policy_file_init(&pf); + pf.type = PF_LEN; + pf.handle = handle; + if (ksu_policydb_write(policydb, &pf)) { + ERR(handle, "could not compute policy length"); + // errno = EINVAL; + goto err; + } + + /* Allocate the new policy image. */ + pf.type = PF_USE_MEMORY; + pf.data = malloc(pf.len); + if (!pf.data) { + ERR(handle, "out of memory"); + goto err; + } + + /* Need to save len and data prior to modification by ksu_policydb_write. */ + tmp_len = pf.len; + tmp_data = pf.data; + + /* Write out the new policy image. */ + if (ksu_policydb_write(policydb, &pf)) { + ERR(handle, "could not write policy"); + // errno = EINVAL; + goto err; + } + + /* Verify the new policy image. */ + pf.type = PF_USE_MEMORY; + pf.data = tmp_data; + pf.len = tmp_len; + if (policydb_init(&tmp_policydb)) { + ERR(handle, "Out of memory"); + // errno = ENOMEM; + goto err; + } + if (ksu_policydb_read(&tmp_policydb, &pf, 0)) { + ERR(handle, "new policy image is invalid"); + // errno = EINVAL; + goto err; + } + ksu_policydb_destroy(&tmp_policydb); + + /* Update (newdata, newlen) */ + *newdata = tmp_data; + *newlen = tmp_len; + + /* Recover */ + return STATUS_SUCCESS; + + err: + ERR(handle, "could not create policy image"); + + /* Recover */ + free(tmp_data); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/policydb_convert.o b/kernel/libsepol/src/policydb_convert.o new file mode 100644 index 00000000..48f9a03d Binary files /dev/null and b/kernel/libsepol/src/policydb_convert.o differ diff --git a/kernel/libsepol/src/policydb_internal.h b/kernel/libsepol/src/policydb_internal.h new file mode 100644 index 00000000..dd8f25d0 --- /dev/null +++ b/kernel/libsepol/src/policydb_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_POLICYDB_INTERNAL_H_ +#define _SEPOL_POLICYDB_INTERNAL_H_ + +#include + +extern const char * const policydb_target_strings[]; +#endif diff --git a/kernel/libsepol/src/policydb_public.c b/kernel/libsepol/src/policydb_public.c new file mode 100644 index 00000000..f8275045 --- /dev/null +++ b/kernel/libsepol/src/policydb_public.c @@ -0,0 +1,214 @@ +// #include + +#include "debug.h" +#include +#include "policydb_internal.h" + +/* Policy file interfaces. */ + +int sepol_policy_file_create(sepol_policy_file_t ** pf) +{ + *pf = calloc(1, sizeof(sepol_policy_file_t)); + if (!(*pf)) + return -1; + return 0; +} + +void sepol_policy_file_set_mem(sepol_policy_file_t * spf, + char *data, size_t len) +{ + struct policy_file *pf = &spf->pf; + if (!len) { + pf->type = PF_LEN; + return; + } + pf->type = PF_USE_MEMORY; + pf->data = data; + pf->len = len; + pf->size = len; + return; +} + +void sepol_policy_file_set_fp(sepol_policy_file_t * spf, FILE * fp) +{ + struct policy_file *pf = &spf->pf; + pf->type = PF_USE_STDIO; + pf->fp = fp; + return; +} + +int sepol_policy_file_get_len(sepol_policy_file_t * spf, size_t * len) +{ + struct policy_file *pf = &spf->pf; + if (pf->type != PF_LEN) + return -1; + *len = pf->len; + return 0; +} + +void sepol_policy_file_set_handle(sepol_policy_file_t * pf, + sepol_handle_t * handle) +{ + pf->pf.handle = handle; +} + +void sepol_policy_file_free(sepol_policy_file_t * pf) +{ + free(pf); +} + +/* Policydb interfaces. */ + +int sepol_policydb_create(sepol_policydb_t ** sp) +{ + policydb_t *p; + *sp = malloc(sizeof(sepol_policydb_t)); + if (!(*sp)) + return -1; + p = &(*sp)->p; + if (policydb_init(p)) { + free(*sp); + *sp = NULL; + return -1; + } + return 0; +} + + +void sepol_policydb_free(sepol_policydb_t * p) +{ + if (!p) + return; + ksu_policydb_destroy(&p->p); + free(p); +} + + +int sepol_policy_kern_vers_min(void) +{ + return POLICYDB_VERSION_MIN; +} + +int sepol_policy_kern_vers_max(void) +{ + return POLICYDB_VERSION_MAX; +} + +int sepol_policydb_set_typevers(sepol_policydb_t * sp, unsigned int type) +{ + struct policydb *p = &sp->p; + switch (type) { + case POLICY_KERN: + p->policyvers = POLICYDB_VERSION_MAX; + break; + case POLICY_BASE: + case POLICY_MOD: + p->policyvers = MOD_POLICYDB_VERSION_MAX; + break; + default: + return -1; + } + p->policy_type = type; + return 0; +} + +int sepol_policydb_set_vers(sepol_policydb_t * sp, unsigned int vers) +{ + struct policydb *p = &sp->p; + switch (p->policy_type) { + case POLICY_KERN: + if (vers < POLICYDB_VERSION_MIN || vers > POLICYDB_VERSION_MAX) + return -1; + break; + case POLICY_BASE: + case POLICY_MOD: + if (vers < MOD_POLICYDB_VERSION_MIN + || vers > MOD_POLICYDB_VERSION_MAX) + return -1; + break; + default: + return -1; + } + p->policyvers = vers; + return 0; +} + +int sepol_policydb_set_handle_unknown(sepol_policydb_t * sp, + unsigned int handle_unknown) +{ + struct policydb *p = &sp->p; + + switch (handle_unknown) { + case SEPOL_DENY_UNKNOWN: + case SEPOL_REJECT_UNKNOWN: + case SEPOL_ALLOW_UNKNOWN: + break; + default: + return -1; + } + + p->handle_unknown = handle_unknown; + return 0; +} + +int sepol_policydb_set_target_platform(sepol_policydb_t * sp, + int target_platform) +{ + struct policydb *p = &sp->p; + + switch (target_platform) { + case SEPOL_TARGET_SELINUX: + case SEPOL_TARGET_XEN: + break; + default: + return -1; + } + + p->target_platform = target_platform; + return 0; +} + +int sepol_policydb_optimize(sepol_policydb_t * p) +{ + return policydb_optimize(&p->p); +} + +int sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf) +{ + return ksu_policydb_read(&p->p, &pf->pf, 0); +} + +int sepol_policydb_write(sepol_policydb_t * p, sepol_policy_file_t * pf) +{ + return ksu_policydb_write(&p->p, &pf->pf); +} + +int sepol_policydb_from_image(sepol_handle_t * handle, + void *data, size_t len, sepol_policydb_t * p) +{ + return policydb_from_image(handle, data, len, &p->p); +} + +int sepol_policydb_to_image(sepol_handle_t * handle, + sepol_policydb_t * p, void **newdata, + size_t * newlen) +{ + return policydb_to_image(handle, &p->p, newdata, newlen); +} + +int sepol_policydb_mls_enabled(const sepol_policydb_t * p) +{ + + return p->p.mls; +} + +/* + * Enable compatibility mode for SELinux network checks iff + * the packet class is not defined in the policy. + */ +#define PACKET_CLASS_NAME "packet" +int sepol_policydb_compat_net(const sepol_policydb_t * p) +{ + return (hashtab_search(p->p.p_classes.table, PACKET_CLASS_NAME) == + NULL); +} diff --git a/kernel/libsepol/src/policydb_public.o b/kernel/libsepol/src/policydb_public.o new file mode 100644 index 00000000..0cf18c7b Binary files /dev/null and b/kernel/libsepol/src/policydb_public.o differ diff --git a/kernel/libsepol/src/policydb_validate.c b/kernel/libsepol/src/policydb_validate.c new file mode 100644 index 00000000..dff2dad3 --- /dev/null +++ b/kernel/libsepol/src/policydb_validate.c @@ -0,0 +1,1387 @@ + +#include +#include +#include +#include + +#include "debug.h" +#include "policydb_validate.h" + +#define bool_xor(a, b) (!(a) != !(b)) +#define bool_xnor(a, b) !bool_xor(a, b) + +typedef struct validate { + uint32_t nprim; + ebitmap_t gaps; +} validate_t; + +typedef struct map_arg { + validate_t *flavors; + sepol_handle_t *handle; + int mls; +} map_arg_t; + +static int create_gap_ebitmap(char **val_to_name, uint32_t nprim, ebitmap_t *gaps) +{ + unsigned int i; + + ebitmap_init(gaps); + + for (i = 0; i < nprim; i++) { + if (!val_to_name[i]) { + if (ksu_ebitmap_set_bit(gaps, i, 1)) + return -1; + } + } + + return 0; +} + +static int validate_init(validate_t *flavor, char **val_to_name, uint32_t nprim) +{ + flavor->nprim = nprim; + if (create_gap_ebitmap(val_to_name, nprim, &flavor->gaps)) + return -1; + + return 0; +} + +static int validate_array_init(policydb_t *p, validate_t flavors[]) +{ + if (validate_init(&flavors[SYM_CLASSES], p->p_class_val_to_name, p->p_classes.nprim)) + goto bad; + if (validate_init(&flavors[SYM_ROLES], p->p_role_val_to_name, p->p_roles.nprim)) + goto bad; + if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) { + if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, p->p_types.nprim)) + goto bad; + } else { + /* + * For policy versions between 20 and 23, attributes exist in the policy, + * but they only exist in the type_attr_map, so there will be references + * to gaps and we just have to treat this case as if there were no gaps. + */ + flavors[SYM_TYPES].nprim = p->p_types.nprim; + ebitmap_init(&flavors[SYM_TYPES].gaps); + } + if (validate_init(&flavors[SYM_USERS], p->p_user_val_to_name, p->p_users.nprim)) + goto bad; + if (validate_init(&flavors[SYM_BOOLS], p->p_bool_val_to_name, p->p_bools.nprim)) + goto bad; + if (validate_init(&flavors[SYM_LEVELS], p->p_sens_val_to_name, p->p_levels.nprim)) + goto bad; + if (validate_init(&flavors[SYM_CATS], p->p_cat_val_to_name, p->p_cats.nprim)) + goto bad; + + return 0; + +bad: + return -1; +} + +/* + * Functions to validate both kernel and module policydbs + */ + +int value_isvalid(uint32_t value, uint32_t nprim) +{ + if (!value || value > nprim) + return 0; + + return 1; +} + +static int validate_value(uint32_t value, validate_t *flavor) +{ + if (!value || value > flavor->nprim) + goto bad; + if (ksu_ebitmap_get_bit(&flavor->gaps, value-1)) + goto bad; + + return 0; + +bad: + return -1; +} + +static int validate_ebitmap(ebitmap_t *map, validate_t *flavor) +{ + if (ebitmap_length(map) > 0 && ebitmap_highest_set_bit(map) >= flavor->nprim) + goto bad; + if (ebitmap_match_any(map, &flavor->gaps)) + goto bad; + + return 0; + +bad: + return -1; +} + +static int validate_type_set(type_set_t *type_set, validate_t *type) +{ + if (validate_ebitmap(&type_set->types, type)) + goto bad; + if (validate_ebitmap(&type_set->negset, type)) + goto bad; + + switch (type_set->flags) { + case 0: + case TYPE_STAR: + case TYPE_COMP: + break; + default: + goto bad; + } + + return 0; + +bad: + return -1; +} + +static int validate_empty_type_set(type_set_t *type_set) +{ + if (!ebitmap_is_empty(&type_set->types)) + goto bad; + if (!ebitmap_is_empty(&type_set->negset)) + goto bad; + if (type_set->flags != 0) + goto bad; + + return 0; + +bad: + return -1; +} + +static int validate_role_set(role_set_t *role_set, validate_t *role) +{ + if (validate_ebitmap(&role_set->roles, role)) + goto bad; + + switch (role_set->flags) { + case 0: + case ROLE_STAR: + case ROLE_COMP: + break; + default: + goto bad; + } + + return 0; + +bad: + return -1; +} + +static int validate_scope(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + scope_datum_t *scope_datum = (scope_datum_t *)d; + uint32_t *nprim = (uint32_t *)args; + unsigned int i; + + switch (scope_datum->scope) { + case SCOPE_REQ: + case SCOPE_DECL: + break; + default: + goto bad; + } + + for (i = 0; i < scope_datum->decl_ids_len; i++) { + if (!value_isvalid(scope_datum->decl_ids[i], *nprim)) + goto bad; + } + + return 0; + +bad: + return -1; +} + +static int validate_scopes(sepol_handle_t *handle, symtab_t scopes[], avrule_block_t *block) +{ + avrule_decl_t *decl; + unsigned int i; + unsigned int num_decls = 0; + + for (; block != NULL; block = block->next) { + for (decl = block->branch_list; decl; decl = decl->next) { + num_decls++; + } + } + + for (i = 0; i < SYM_NUM; i++) { + if (ksu_hashtab_map(scopes[i].table, validate_scope, &num_decls)) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid scope"); + return -1; +} + +static int validate_constraint_nodes(sepol_handle_t *handle, unsigned int nperms, constraint_node_t *cons, validate_t flavors[]) +{ + constraint_expr_t *cexp; + + for (; cons; cons = cons->next) { + if (nperms == 0 && cons->permissions != 0) + goto bad; + if (nperms > 0 && cons->permissions == 0) + goto bad; + if (nperms > 0 && nperms != PERM_SYMTAB_SIZE && cons->permissions >= (UINT32_C(1) << nperms)) + goto bad; + + for (cexp = cons->expr; cexp; cexp = cexp->next) { + if (cexp->expr_type == CEXPR_NAMES) { + if (cexp->attr & CEXPR_XTARGET && nperms != 0) + goto bad; + if (!(cexp->attr & CEXPR_TYPE)) { + if (validate_empty_type_set(cexp->type_names)) + goto bad; + } + + switch (cexp->op) { + case CEXPR_EQ: + case CEXPR_NEQ: + break; + default: + goto bad; + } + + switch (cexp->attr) { + case CEXPR_USER: + case CEXPR_USER | CEXPR_TARGET: + case CEXPR_USER | CEXPR_XTARGET: + if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS])) + goto bad; + break; + case CEXPR_ROLE: + case CEXPR_ROLE | CEXPR_TARGET: + case CEXPR_ROLE | CEXPR_XTARGET: + if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES])) + goto bad; + break; + case CEXPR_TYPE: + case CEXPR_TYPE | CEXPR_TARGET: + case CEXPR_TYPE | CEXPR_XTARGET: + if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES])) + goto bad; + if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES])) + goto bad; + break; + default: + goto bad; + } + } else if (cexp->expr_type == CEXPR_ATTR) { + if (!ebitmap_is_empty(&cexp->names)) + goto bad; + if (validate_empty_type_set(cexp->type_names)) + goto bad; + + switch (cexp->op) { + case CEXPR_EQ: + case CEXPR_NEQ: + break; + case CEXPR_DOM: + case CEXPR_DOMBY: + case CEXPR_INCOMP: + if ((cexp->attr & CEXPR_USER) || (cexp->attr & CEXPR_TYPE)) + goto bad; + break; + default: + goto bad; + } + + switch (cexp->attr) { + case CEXPR_USER: + case CEXPR_ROLE: + case CEXPR_TYPE: + case CEXPR_L1L2: + case CEXPR_L1H2: + case CEXPR_H1L2: + case CEXPR_H1H2: + case CEXPR_L1H1: + case CEXPR_L2H2: + break; + default: + goto bad; + } + } else { + switch (cexp->expr_type) { + case CEXPR_NOT: + case CEXPR_AND: + case CEXPR_OR: + break; + default: + goto bad; + } + + if (cexp->op != 0) + goto bad; + if (cexp->attr != 0) + goto bad; + if (!ebitmap_is_empty(&cexp->names)) + goto bad; + if (validate_empty_type_set(cexp->type_names)) + goto bad; + } + } + } + + return 0; + +bad: + ERR(handle, "Invalid constraint expr"); + return -1; +} + +static int validate_class_datum(sepol_handle_t *handle, class_datum_t *class, validate_t flavors[]) +{ + if (validate_value(class->s.value, &flavors[SYM_CLASSES])) + goto bad; + if (class->permissions.nprim > PERM_SYMTAB_SIZE) + goto bad; + if (validate_constraint_nodes(handle, class->permissions.nprim, class->constraints, flavors)) + goto bad; + if (validate_constraint_nodes(handle, 0, class->validatetrans, flavors)) + goto bad; + + switch (class->default_user) { + case 0: + case DEFAULT_SOURCE: + case DEFAULT_TARGET: + break; + default: + goto bad; + } + + switch (class->default_role) { + case 0: + case DEFAULT_SOURCE: + case DEFAULT_TARGET: + break; + default: + goto bad; + } + + switch (class->default_type) { + case 0: + case DEFAULT_SOURCE: + case DEFAULT_TARGET: + break; + default: + goto bad; + } + + switch (class->default_range) { + case 0: + case DEFAULT_SOURCE_LOW: + case DEFAULT_SOURCE_HIGH: + case DEFAULT_SOURCE_LOW_HIGH: + case DEFAULT_TARGET_LOW: + case DEFAULT_TARGET_HIGH: + case DEFAULT_TARGET_LOW_HIGH: + case DEFAULT_GLBLUB: + break; + default: + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid class datum"); + return -1; +} + +static int validate_class_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + map_arg_t *margs = args; + + return validate_class_datum(margs->handle, d, margs->flavors); +} + +static int validate_common_datum(sepol_handle_t *handle, common_datum_t *common) +{ + if (common->permissions.nprim > PERM_SYMTAB_SIZE) + goto bad; + + return 0; + +bad: + ERR(handle, "Invalid common class datum"); + return -1; +} + +static int validate_common_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + map_arg_t *margs = args; + + return validate_common_datum(margs->handle, d); +} + +static int validate_role_datum(sepol_handle_t *handle, role_datum_t *role, validate_t flavors[]) +{ + if (validate_value(role->s.value, &flavors[SYM_ROLES])) + goto bad; + if (validate_ebitmap(&role->dominates, &flavors[SYM_ROLES])) + goto bad; + if (validate_type_set(&role->types, &flavors[SYM_TYPES])) + goto bad; + if (role->bounds && validate_value(role->bounds, &flavors[SYM_ROLES])) + goto bad; + if (validate_ebitmap(&role->roles, &flavors[SYM_ROLES])) + goto bad; + + return 0; + +bad: + ERR(handle, "Invalid role datum"); + return -1; +} + +static int validate_role_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + map_arg_t *margs = args; + + return validate_role_datum(margs->handle, d, margs->flavors); +} + +static int validate_type_datum(sepol_handle_t *handle, type_datum_t *type, validate_t flavors[]) +{ + if (validate_value(type->s.value, &flavors[SYM_TYPES])) + goto bad; + if (validate_ebitmap(&type->types, &flavors[SYM_TYPES])) + goto bad; + if (type->bounds && validate_value(type->bounds, &flavors[SYM_TYPES])) + goto bad; + + switch (type->flavor) { + case TYPE_TYPE: + case TYPE_ATTRIB: + case TYPE_ALIAS: + break; + default: + goto bad; + } + + switch (type->flags) { + case 0: + case TYPE_FLAGS_PERMISSIVE: + case TYPE_FLAGS_EXPAND_ATTR_TRUE: + case TYPE_FLAGS_EXPAND_ATTR_FALSE: + case TYPE_FLAGS_EXPAND_ATTR: + break; + default: + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid type datum"); + return -1; +} + +static int validate_type_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + map_arg_t *margs = args; + + return validate_type_datum(margs->handle, d, margs->flavors); +} + +static int validate_mls_semantic_cat(mls_semantic_cat_t *cat, validate_t *cats) +{ + for (; cat; cat = cat->next) { + if (validate_value(cat->low, cats)) + goto bad; + if (validate_value(cat->high, cats)) + goto bad; + } + + return 0; + +bad: + return -1; +} + +static int validate_mls_semantic_level(mls_semantic_level_t *level, validate_t *sens, validate_t *cats) +{ + if (level->sens == 0) + return 0; + if (validate_value(level->sens, sens)) + goto bad; + if (validate_mls_semantic_cat(level->cat, cats)) + goto bad; + + return 0; + +bad: + return -1; +} + +static int validate_mls_semantic_range(mls_semantic_range_t *range, validate_t *sens, validate_t *cats) +{ + if (validate_mls_semantic_level(&range->level[0], sens, cats)) + goto bad; + if (validate_mls_semantic_level(&range->level[1], sens, cats)) + goto bad; + + return 0; + +bad: + return -1; +} + +static int validate_mls_level(mls_level_t *level, validate_t *sens, validate_t *cats) +{ + if (validate_value(level->sens, sens)) + goto bad; + if (validate_ebitmap(&level->cat, cats)) + goto bad; + + return 0; + + bad: + return -1; +} + +static int validate_level_datum(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + level_datum_t *level = d; + validate_t *flavors = args; + + return validate_mls_level(level->level, &flavors[SYM_LEVELS], &flavors[SYM_CATS]); +} + +static int validate_mls_range(mls_range_t *range, validate_t *sens, validate_t *cats) +{ + if (validate_mls_level(&range->level[0], sens, cats)) + goto bad; + if (validate_mls_level(&range->level[1], sens, cats)) + goto bad; + + return 0; + + bad: + return -1; +} + +static int validate_user_datum(sepol_handle_t *handle, user_datum_t *user, validate_t flavors[], int mls) +{ + if (validate_value(user->s.value, &flavors[SYM_USERS])) + goto bad; + if (validate_role_set(&user->roles, &flavors[SYM_ROLES])) + goto bad; + if (validate_mls_semantic_range(&user->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) + goto bad; + if (validate_mls_semantic_level(&user->dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) + goto bad; + if (mls && validate_mls_range(&user->exp_range, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) + goto bad; + if (mls && validate_mls_level(&user->exp_dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) + goto bad; + if (user->bounds && validate_value(user->bounds, &flavors[SYM_USERS])) + goto bad; + + return 0; + +bad: + ERR(handle, "Invalid user datum"); + return -1; +} + +static int validate_user_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + map_arg_t *margs = args; + + return validate_user_datum(margs->handle, d, margs->flavors, margs->mls); +} + +static int validate_bool_datum(sepol_handle_t *handle, cond_bool_datum_t *boolean, validate_t flavors[]) +{ + if (validate_value(boolean->s.value, &flavors[SYM_BOOLS])) + goto bad; + + switch (boolean->state) { + case 0: + case 1: + break; + default: + goto bad; + } + + switch (boolean->flags) { + case 0: + case COND_BOOL_FLAGS_TUNABLE: + break; + default: + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid bool datum"); + return -1; +} + +static int validate_bool_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + map_arg_t *margs = args; + + return validate_bool_datum(margs->handle, d, margs->flavors); +} + +static int validate_datum_array_gaps(sepol_handle_t *handle, policydb_t *p, validate_t flavors[]) +{ + unsigned int i; + + for (i = 0; i < p->p_classes.nprim; i++) { + if (bool_xnor(p->class_val_to_struct[i], ksu_ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i))) + goto bad; + } + + for (i = 0; i < p->p_roles.nprim; i++) { + if (bool_xnor(p->role_val_to_struct[i], ksu_ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i))) + goto bad; + } + + /* + * For policy versions between 20 and 23, attributes exist in the policy, + * but only in the type_attr_map, so all gaps must be assumed to be valid. + */ + if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) { + for (i = 0; i < p->p_types.nprim; i++) { + if (bool_xnor(p->type_val_to_struct[i], ksu_ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i))) + goto bad; + } + } + + for (i = 0; i < p->p_users.nprim; i++) { + if (bool_xnor(p->user_val_to_struct[i], ksu_ebitmap_get_bit(&flavors[SYM_USERS].gaps, i))) + goto bad; + } + + for (i = 0; i < p->p_bools.nprim; i++) { + if (bool_xnor(p->bool_val_to_struct[i], ksu_ebitmap_get_bit(&flavors[SYM_BOOLS].gaps, i))) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid datum array gaps"); + return -1; +} + +static int validate_datum(__attribute__ ((unused))hashtab_key_t k, hashtab_datum_t d, void *args) +{ + symtab_datum_t *s = d; + uint32_t *nprim = (uint32_t *)args; + + return !value_isvalid(s->value, *nprim); +} + +static int validate_datum_array_entries(sepol_handle_t *handle, policydb_t *p, validate_t flavors[]) +{ + map_arg_t margs = { flavors, handle, p->mls }; + + if (ksu_hashtab_map(p->p_commons.table, validate_common_datum_wrapper, &margs)) + goto bad; + + if (ksu_hashtab_map(p->p_classes.table, validate_class_datum_wrapper, &margs)) + goto bad; + + if (ksu_hashtab_map(p->p_roles.table, validate_role_datum_wrapper, &margs)) + goto bad; + + if (ksu_hashtab_map(p->p_types.table, validate_type_datum_wrapper, &margs)) + goto bad; + + if (ksu_hashtab_map(p->p_users.table, validate_user_datum_wrapper, &margs)) + goto bad; + + if (p->mls && ksu_hashtab_map(p->p_levels.table, validate_level_datum, flavors)) + goto bad; + + if (ksu_hashtab_map(p->p_cats.table, validate_datum, &flavors[SYM_CATS])) + goto bad; + + if (ksu_hashtab_map(p->p_bools.table, validate_bool_datum_wrapper, &margs)) + goto bad; + + return 0; + +bad: + ERR(handle, "Invalid datum array entries"); + return -1; +} + +/* + * Functions to validate a kernel policydb + */ + +static int validate_avtab_key(avtab_key_t *key, int conditional, validate_t flavors[]) +{ + if (validate_value(key->source_type, &flavors[SYM_TYPES])) + goto bad; + if (validate_value(key->target_type, &flavors[SYM_TYPES])) + goto bad; + if (validate_value(key->target_class, &flavors[SYM_CLASSES])) + goto bad; + switch (0xFFF & key->specified) { + case AVTAB_ALLOWED: + case AVTAB_AUDITALLOW: + case AVTAB_AUDITDENY: + case AVTAB_TRANSITION: + case AVTAB_MEMBER: + case AVTAB_CHANGE: + break; + case AVTAB_XPERMS_ALLOWED: + case AVTAB_XPERMS_AUDITALLOW: + case AVTAB_XPERMS_DONTAUDIT: + if (conditional) + goto bad; + break; + default: + goto bad; + } + + return 0; + +bad: + return -1; +} + +static int validate_avtab_key_and_datum(avtab_key_t *k, avtab_datum_t *d, void *args) +{ + validate_t *flavors = (validate_t *)args; + + if (validate_avtab_key(k, 0, flavors)) + return -1; + + if ((k->specified & AVTAB_TYPE) && validate_value(d->data, &flavors[SYM_TYPES])) + return -1; + + return 0; +} + +static int validate_avtab(sepol_handle_t *handle, avtab_t *avtab, validate_t flavors[]) +{ + if (avtab_map(avtab, validate_avtab_key_and_datum, flavors)) { + ERR(handle, "Invalid avtab"); + return -1; + } + + return 0; +} + +static int validate_cond_av_list(sepol_handle_t *handle, cond_av_list_t *cond_av, validate_t flavors[]) +{ + avtab_ptr_t avtab_ptr; + + for (; cond_av; cond_av = cond_av->next) { + for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) { + if (validate_avtab_key(&avtab_ptr->key, 1, flavors)) { + ERR(handle, "Invalid cond av list"); + return -1; + } + } + } + + return 0; +} + +static int validate_avrules(sepol_handle_t *handle, avrule_t *avrule, int conditional, validate_t flavors[]) +{ + class_perm_node_t *class; + + for (; avrule; avrule = avrule->next) { + if (validate_type_set(&avrule->stypes, &flavors[SYM_TYPES])) + goto bad; + if (validate_type_set(&avrule->ttypes, &flavors[SYM_TYPES])) + goto bad; + class = avrule->perms; + for (; class; class = class->next) { + if (validate_value(class->tclass, &flavors[SYM_CLASSES])) + goto bad; + } + + switch(avrule->specified) { + case AVRULE_ALLOWED: + case AVRULE_AUDITALLOW: + case AVRULE_AUDITDENY: + case AVRULE_DONTAUDIT: + case AVRULE_TRANSITION: + case AVRULE_MEMBER: + case AVRULE_CHANGE: + break; + case AVRULE_NEVERALLOW: + case AVRULE_XPERMS_ALLOWED: + case AVRULE_XPERMS_AUDITALLOW: + case AVRULE_XPERMS_DONTAUDIT: + case AVRULE_XPERMS_NEVERALLOW: + if (conditional) + goto bad; + break; + default: + goto bad; + } + + if (avrule->specified & AVRULE_XPERMS) { + if (!avrule->xperms) + goto bad; + switch (avrule->xperms->specified) { + case AVRULE_XPERMS_IOCTLFUNCTION: + case AVRULE_XPERMS_IOCTLDRIVER: + break; + default: + goto bad; + } + } else if (avrule->xperms) + goto bad; + + switch(avrule->flags) { + case 0: + case RULE_SELF: + break; + default: + goto bad; + } + } + + return 0; + +bad: + ERR(handle, "Invalid avrule"); + return -1; +} + +static int validate_bool_id_array(sepol_handle_t *handle, uint32_t bool_ids[], unsigned int nbools, validate_t *bool) +{ + unsigned int i; + + if (nbools >= COND_MAX_BOOLS) + goto bad; + + for (i=0; i < nbools; i++) { + if (validate_value(bool_ids[i], bool)) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid bool id array"); + return -1; +} + +static int validate_cond_expr(sepol_handle_t *handle, struct cond_expr *expr, validate_t *bool) +{ + int depth = -1; + + for (; expr; expr = expr->next) { + switch(expr->expr_type) { + case COND_BOOL: + if (validate_value(expr->bool, bool)) + goto bad; + if (depth == (COND_EXPR_MAXDEPTH - 1)) + goto bad; + depth++; + break; + case COND_NOT: + if (depth < 0) + goto bad; + break; + case COND_OR: + case COND_AND: + case COND_XOR: + case COND_EQ: + case COND_NEQ: + if (depth < 1) + goto bad; + depth--; + break; + default: + goto bad; + } + } + + if (depth != 0) + goto bad; + + return 0; + +bad: + ERR(handle, "Invalid cond expression"); + return -1; +} + +static int validate_cond_list(sepol_handle_t *handle, cond_list_t *cond, validate_t flavors[]) +{ + for (; cond; cond = cond->next) { + if (validate_cond_expr(handle, cond->expr, &flavors[SYM_BOOLS])) + goto bad; + if (validate_cond_av_list(handle, cond->true_list, flavors)) + goto bad; + if (validate_cond_av_list(handle, cond->false_list, flavors)) + goto bad; + if (validate_avrules(handle, cond->avtrue_list, 1, flavors)) + goto bad; + if (validate_avrules(handle, cond->avfalse_list, 1, flavors)) + goto bad; + if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS])) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid cond list"); + return -1; +} + +static int validate_role_transes(sepol_handle_t *handle, role_trans_t *role_trans, validate_t flavors[]) +{ + for (; role_trans; role_trans = role_trans->next) { + if (validate_value(role_trans->role, &flavors[SYM_ROLES])) + goto bad; + if (validate_value(role_trans->type, &flavors[SYM_TYPES])) + goto bad; + if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES])) + goto bad; + if (validate_value(role_trans->new_role, &flavors[SYM_ROLES])) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid role trans"); + return -1; +} + +static int validate_role_allows(sepol_handle_t *handle, role_allow_t *role_allow, validate_t flavors[]) +{ + for (; role_allow; role_allow = role_allow->next) { + if (validate_value(role_allow->role, &flavors[SYM_ROLES])) + goto bad; + if (validate_value(role_allow->new_role, &flavors[SYM_ROLES])) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid role allow"); + return -1; +} + +static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args) +{ + filename_trans_key_t *ftk = (filename_trans_key_t *)k; + filename_trans_datum_t *ftd = d; + validate_t *flavors = (validate_t *)args; + + if (validate_value(ftk->ttype, &flavors[SYM_TYPES])) + goto bad; + if (validate_value(ftk->tclass, &flavors[SYM_CLASSES])) + goto bad; + for (; ftd; ftd = ftd->next) { + if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES])) + goto bad; + if (validate_value(ftd->otype, &flavors[SYM_TYPES])) + goto bad; + } + + return 0; + +bad: + return -1; +} + +static int validate_filename_trans_hashtab(sepol_handle_t *handle, hashtab_t filename_trans, validate_t flavors[]) +{ + if (ksu_hashtab_map(filename_trans, validate_filename_trans, flavors)) { + ERR(handle, "Invalid filename trans"); + return -1; + } + + return 0; +} + +static int validate_context(context_struct_t *con, validate_t flavors[], int mls) +{ + if (validate_value(con->user, &flavors[SYM_USERS])) + return -1; + if (validate_value(con->role, &flavors[SYM_ROLES])) + return -1; + if (validate_value(con->type, &flavors[SYM_TYPES])) + return -1; + if (mls && validate_mls_range(&con->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) + return -1; + + return 0; +} + +static int validate_ocontexts(sepol_handle_t *handle, policydb_t *p, validate_t flavors[]) +{ + ocontext_t *octx; + unsigned int i; + + for (i = 0; i < OCON_NUM; i++) { + for (octx = p->ocontexts[i]; octx; octx = octx->next) { + if (validate_context(&octx->context[0], flavors, p->mls)) + goto bad; + + if (p->target_platform == SEPOL_TARGET_SELINUX) { + switch (i) { + case OCON_FS: + case OCON_NETIF: + if (validate_context(&octx->context[1], flavors, p->mls)) + goto bad; + break; + case OCON_FSUSE: + switch (octx->v.behavior) { + case SECURITY_FS_USE_XATTR: + case SECURITY_FS_USE_TRANS: + case SECURITY_FS_USE_TASK: + break; + default: + goto bad; + } + } + } + } + } + + return 0; + +bad: + ERR(handle, "Invalid ocontext"); + return -1; +} + +static int validate_genfs(sepol_handle_t *handle, policydb_t *p, validate_t flavors[]) +{ + genfs_t *genfs; + ocontext_t *octx; + + for (genfs = p->genfs; genfs; genfs = genfs->next) { + for (octx = genfs->head; octx; octx = octx->next) { + if (validate_context(&octx->context[0], flavors, p->mls)) + goto bad; + } + } + + return 0; + +bad: + ERR(handle, "Invalid genfs"); + return -1; +} + +/* + * Functions to validate a module policydb + */ + +static int validate_role_trans_rules(sepol_handle_t *handle, role_trans_rule_t *role_trans, validate_t flavors[]) +{ + for (; role_trans; role_trans = role_trans->next) { + if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES])) + goto bad; + if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES])) + goto bad; + if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES])) + goto bad; + if (validate_value(role_trans->new_role, &flavors[SYM_ROLES])) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid role trans rule"); + return -1; +} + +static int validate_role_allow_rules(sepol_handle_t *handle, role_allow_rule_t *role_allow, validate_t flavors[]) +{ + for (; role_allow; role_allow = role_allow->next) { + if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES])) + goto bad; + if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES])) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid role allow rule"); + return -1; +} + +static int validate_range_trans_rules(sepol_handle_t *handle, range_trans_rule_t *range_trans, validate_t flavors[]) +{ + for (; range_trans; range_trans = range_trans->next) { + if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES])) + goto bad; + if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES])) + goto bad; + if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES])) + goto bad; + if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid range trans rule"); + return -1; +} + +static int validate_scope_index(sepol_handle_t *handle, scope_index_t *scope_index, validate_t flavors[]) +{ + if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES])) + goto bad; + if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES])) + goto bad; + if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES])) + goto bad; + if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS])) + goto bad; + if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS])) + goto bad; + if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS])) + goto bad; + if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS])) + goto bad; + if (scope_index->class_perms_len > flavors[SYM_CLASSES].nprim) + goto bad; + + return 0; + +bad: + ERR(handle, "Invalid scope"); + return -1; +} + + +static int validate_filename_trans_rules(sepol_handle_t *handle, filename_trans_rule_t *filename_trans, validate_t flavors[]) +{ + for (; filename_trans; filename_trans = filename_trans->next) { + if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES])) + goto bad; + if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES])) + goto bad; + if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] )) + goto bad; + if (validate_value(filename_trans->otype, &flavors[SYM_TYPES])) + goto bad; + + /* currently only the RULE_SELF flag can be set */ + if ((filename_trans->flags & ~RULE_SELF) != 0) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid filename trans rule list"); + return -1; +} + +static int validate_symtabs(sepol_handle_t *handle, symtab_t symtabs[], validate_t flavors[]) +{ + unsigned int i; + + for (i = 0; i < SYM_NUM; i++) { + if (ksu_hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) { + ERR(handle, "Invalid symtab"); + return -1; + } + } + + return 0; +} + +static int validate_avrule_blocks(sepol_handle_t *handle, avrule_block_t *avrule_block, validate_t flavors[]) +{ + avrule_decl_t *decl; + + for (; avrule_block; avrule_block = avrule_block->next) { + for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) { + if (validate_cond_list(handle, decl->cond_list, flavors)) + goto bad; + if (validate_avrules(handle, decl->avrules, 0, flavors)) + goto bad; + if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors)) + goto bad; + if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors)) + goto bad; + if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors)) + goto bad; + if (validate_scope_index(handle, &decl->required, flavors)) + goto bad; + if (validate_scope_index(handle, &decl->declared, flavors)) + goto bad; + if (validate_filename_trans_rules(handle, decl->filename_trans_rules, flavors)) + goto bad; + if (validate_symtabs(handle, decl->symtab, flavors)) + goto bad; + } + + switch (avrule_block->flags) { + case 0: + case AVRULE_OPTIONAL: + break; + default: + goto bad; + } + } + + return 0; + +bad: + ERR(handle, "Invalid avrule block"); + return -1; +} + +static int validate_permissives(sepol_handle_t *handle, policydb_t *p, validate_t flavors[]) +{ + ebitmap_node_t *node; + unsigned i; + + ebitmap_for_each_positive_bit(&p->permissive_map, node, i) { + if (validate_value(i, &flavors[SYM_TYPES])) + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid permissive type"); + return -1; +} + +static int validate_properties(sepol_handle_t *handle, policydb_t *p) +{ + switch (p->policy_type) { + case POLICY_KERN: + if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX) + goto bad; + break; + case POLICY_BASE: + case POLICY_MOD: + if (p->policyvers < MOD_POLICYDB_VERSION_MIN || p->policyvers > MOD_POLICYDB_VERSION_MAX) + goto bad; + break; + default: + goto bad; + } + + switch (p->target_platform) { + case SEPOL_TARGET_SELINUX: + case SEPOL_TARGET_XEN: + break; + default: + goto bad; + } + + switch (p->mls) { + case 0: + case 1: + break; + default: + goto bad; + } + + switch (p->handle_unknown) { + case SEPOL_DENY_UNKNOWN: + case SEPOL_REJECT_UNKNOWN: + case SEPOL_ALLOW_UNKNOWN: + break; + default: + goto bad; + } + + return 0; + +bad: + ERR(handle, "Invalid policy property"); + return -1; +} + +static void validate_array_destroy(validate_t flavors[]) +{ + unsigned int i; + + for (i = 0; i < SYM_NUM; i++) { + ksu_ebitmap_destroy(&flavors[i].gaps); + } +} + +/* + * Validate policydb + */ +int validate_policydb(sepol_handle_t *handle, policydb_t *p) +{ + validate_t flavors[SYM_NUM] = {}; + + if (validate_array_init(p, flavors)) + goto bad; + + if (validate_properties(handle, p)) + goto bad; + + if (p->policy_type == POLICY_KERN) { + if (validate_avtab(handle, &p->te_avtab, flavors)) + goto bad; + if (p->policyvers >= POLICYDB_VERSION_BOOL) + if (validate_cond_list(handle, p->cond_list, flavors)) + goto bad; + if (validate_role_transes(handle, p->role_tr, flavors)) + goto bad; + if (validate_role_allows(handle, p->role_allow, flavors)) + goto bad; + if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) + if (validate_filename_trans_hashtab(handle, p->filename_trans, flavors)) + goto bad; + } else { + if (validate_avrule_blocks(handle, p->global, flavors)) + goto bad; + } + + if (validate_ocontexts(handle, p, flavors)) + goto bad; + + if (validate_genfs(handle, p, flavors)) + goto bad; + + if (validate_scopes(handle, p->scope, p->global)) + goto bad; + + if (validate_datum_array_gaps(handle, p, flavors)) + goto bad; + + if (validate_datum_array_entries(handle, p, flavors)) + goto bad; + + if (validate_permissives(handle, p, flavors)) + goto bad; + + validate_array_destroy(flavors); + + return 0; + +bad: + ERR(handle, "Invalid policydb"); + validate_array_destroy(flavors); + return -1; +} diff --git a/kernel/libsepol/src/policydb_validate.h b/kernel/libsepol/src/policydb_validate.h new file mode 100644 index 00000000..1ffd28c5 --- /dev/null +++ b/kernel/libsepol/src/policydb_validate.h @@ -0,0 +1,7 @@ +// #include + +#include +#include + +int value_isvalid(uint32_t value, uint32_t nprim); +int validate_policydb(sepol_handle_t *handle, policydb_t *p); diff --git a/kernel/libsepol/src/policydb_validate.o b/kernel/libsepol/src/policydb_validate.o new file mode 100644 index 00000000..ae5a9e3a Binary files /dev/null and b/kernel/libsepol/src/policydb_validate.o differ diff --git a/kernel/libsepol/src/port_internal.h b/kernel/libsepol/src/port_internal.h new file mode 100644 index 00000000..80cf5c25 --- /dev/null +++ b/kernel/libsepol/src/port_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_PORT_INTERNAL_H_ +#define _SEPOL_PORT_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/port_record.c b/kernel/libsepol/src/port_record.c new file mode 100644 index 00000000..c8240562 --- /dev/null +++ b/kernel/libsepol/src/port_record.c @@ -0,0 +1,280 @@ +// #include +#include + +#include "port_internal.h" +#include "context_internal.h" +#include "debug.h" + +struct sepol_port { + /* Low - High range. Same for single ports. */ + int low, high; + + /* Protocol */ + int proto; + + /* Context */ + sepol_context_t *con; +}; + +struct sepol_port_key { + /* Low - High range. Same for single ports. */ + int low, high; + + /* Protocol */ + int proto; +}; + +/* Key */ +int sepol_port_key_create(sepol_handle_t * handle, + int low, int high, int proto, + sepol_port_key_t ** key_ptr) +{ + + sepol_port_key_t *tmp_key = + (sepol_port_key_t *) malloc(sizeof(sepol_port_key_t)); + + if (!tmp_key) { + ERR(handle, "out of memory, could not create " "port key"); + return STATUS_ERR; + } + + tmp_key->low = low; + tmp_key->high = high; + tmp_key->proto = proto; + + *key_ptr = tmp_key; + return STATUS_SUCCESS; +} + + +void sepol_port_key_unpack(const sepol_port_key_t * key, + int *low, int *high, int *proto) +{ + + *low = key->low; + *high = key->high; + *proto = key->proto; +} + + +int sepol_port_key_extract(sepol_handle_t * handle, + const sepol_port_t * port, + sepol_port_key_t ** key_ptr) +{ + + if (sepol_port_key_create + (handle, port->low, port->high, port->proto, key_ptr) < 0) { + + ERR(handle, "could not extract key from port %s %d:%d", + sepol_port_get_proto_str(port->proto), + port->low, port->high); + + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_port_key_free(sepol_port_key_t * key) +{ + free(key); +} + +int sepol_port_compare(const sepol_port_t * port, const sepol_port_key_t * key) +{ + + if ((port->low == key->low) && + (port->high == key->high) && (port->proto == key->proto)) + return 0; + + if (port->low < key->low) + return -1; + + else if (key->low < port->low) + return 1; + + else if (port->high < key->high) + return -1; + + else if (key->high < port->high) + return 1; + + else if (port->proto < key->proto) + return -1; + + else + return 1; +} + +int sepol_port_compare2(const sepol_port_t * port, const sepol_port_t * port2) +{ + + if ((port->low == port2->low) && + (port->high == port2->high) && (port->proto == port2->proto)) + return 0; + + if (port->low < port2->low) + return -1; + + else if (port2->low < port->low) + return 1; + + else if (port->high < port2->high) + return -1; + + else if (port2->high < port->high) + return 1; + + else if (port->proto < port2->proto) + return -1; + + else + return 1; +} + +/* Port */ +int sepol_port_get_low(const sepol_port_t * port) +{ + + return port->low; +} + + +int sepol_port_get_high(const sepol_port_t * port) +{ + + return port->high; +} + + +void sepol_port_set_port(sepol_port_t * port, int port_num) +{ + + port->low = port_num; + port->high = port_num; +} + +void sepol_port_set_range(sepol_port_t * port, int low, int high) +{ + + port->low = low; + port->high = high; +} + + +/* Protocol */ +int sepol_port_get_proto(const sepol_port_t * port) +{ + + return port->proto; +} + + +const char *sepol_port_get_proto_str(int proto) +{ + + switch (proto) { + case SEPOL_PROTO_UDP: + return "udp"; + case SEPOL_PROTO_TCP: + return "tcp"; + case SEPOL_PROTO_DCCP: + return "dccp"; + case SEPOL_PROTO_SCTP: + return "sctp"; + default: + return "???"; + } +} + + +void sepol_port_set_proto(sepol_port_t * port, int proto) +{ + + port->proto = proto; +} + + +/* Create */ +int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port) +{ + + sepol_port_t *tmp_port = (sepol_port_t *) malloc(sizeof(sepol_port_t)); + + if (!tmp_port) { + ERR(handle, "out of memory, could not create " "port record"); + return STATUS_ERR; + } + + tmp_port->low = 0; + tmp_port->high = 0; + tmp_port->proto = SEPOL_PROTO_UDP; + tmp_port->con = NULL; + *port = tmp_port; + + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_port_clone(sepol_handle_t * handle, + const sepol_port_t * port, sepol_port_t ** port_ptr) +{ + + sepol_port_t *new_port = NULL; + if (sepol_port_create(handle, &new_port) < 0) + goto err; + + new_port->low = port->low; + new_port->high = port->high; + new_port->proto = port->proto; + + if (port->con && + (sepol_context_clone(handle, port->con, &new_port->con) < 0)) + goto err; + + *port_ptr = new_port; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not clone port record"); + sepol_port_free(new_port); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_port_free(sepol_port_t * port) +{ + + if (!port) + return; + + sepol_context_free(port->con); + free(port); +} + + +/* Context */ +sepol_context_t *sepol_port_get_con(const sepol_port_t * port) +{ + + return port->con; +} + + +int sepol_port_set_con(sepol_handle_t * handle, + sepol_port_t * port, sepol_context_t * con) +{ + + sepol_context_t *newcon; + + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set port context"); + return STATUS_ERR; + } + + sepol_context_free(port->con); + port->con = newcon; + return STATUS_SUCCESS; +} + diff --git a/kernel/libsepol/src/port_record.o b/kernel/libsepol/src/port_record.o new file mode 100644 index 00000000..18a0de37 Binary files /dev/null and b/kernel/libsepol/src/port_record.o differ diff --git a/kernel/libsepol/src/ports.c b/kernel/libsepol/src/ports.c new file mode 100644 index 00000000..712b0d1a --- /dev/null +++ b/kernel/libsepol/src/ports.c @@ -0,0 +1,326 @@ +// #include +#include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif +// #include + +#include "debug.h" +#include "context.h" +#include "handle.h" + +#include +#include "port_internal.h" + +static inline int sepol2ipproto(sepol_handle_t * handle, int proto) +{ + + switch (proto) { + case SEPOL_PROTO_TCP: + return IPPROTO_TCP; + case SEPOL_PROTO_UDP: + return IPPROTO_UDP; + case SEPOL_PROTO_DCCP: + return IPPROTO_DCCP; + case SEPOL_PROTO_SCTP: + return IPPROTO_SCTP; + default: + ERR(handle, "unsupported protocol %u", proto); + return STATUS_ERR; + } +} + +static inline int ipproto2sepol(sepol_handle_t * handle, int proto) +{ + + switch (proto) { + case IPPROTO_TCP: + return SEPOL_PROTO_TCP; + case IPPROTO_UDP: + return SEPOL_PROTO_UDP; + case IPPROTO_DCCP: + return SEPOL_PROTO_DCCP; + case IPPROTO_SCTP: + return SEPOL_PROTO_SCTP; + default: + ERR(handle, "invalid protocol %u " "found in policy", proto); + return STATUS_ERR; + } +} + +/* Create a low level port structure from + * a high level representation */ +static int port_from_record(sepol_handle_t * handle, + const policydb_t * policydb, + ocontext_t ** port, const sepol_port_t * data) +{ + + ocontext_t *tmp_port = NULL; + context_struct_t *tmp_con = NULL; + int tmp_proto; + + int low = sepol_port_get_low(data); + int high = sepol_port_get_high(data); + int proto = sepol_port_get_proto(data); + + tmp_port = (ocontext_t *) calloc(1, sizeof(ocontext_t)); + if (!tmp_port) + goto omem; + + /* Process protocol */ + tmp_proto = sepol2ipproto(handle, proto); + if (tmp_proto < 0) + goto err; + tmp_port->u.port.protocol = tmp_proto; + + /* Port range */ + tmp_port->u.port.low_port = low; + tmp_port->u.port.high_port = high; + if (tmp_port->u.port.low_port > tmp_port->u.port.high_port) { + ERR(handle, "low port %d exceeds high port %d", + tmp_port->u.port.low_port, tmp_port->u.port.high_port); + goto err; + } + + /* Context */ + if (context_from_record(handle, policydb, &tmp_con, + sepol_port_get_con(data)) < 0) + goto err; + context_cpy(&tmp_port->context[0], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + *port = tmp_port; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + if (tmp_port != NULL) { + context_destroy(&tmp_port->context[0]); + free(tmp_port); + } + context_destroy(tmp_con); + free(tmp_con); + ERR(handle, "could not create port structure for range %u:%u (%s)", + low, high, sepol_port_get_proto_str(proto)); + return STATUS_ERR; +} + +static int port_to_record(sepol_handle_t * handle, + const policydb_t * policydb, + ocontext_t * port, sepol_port_t ** record) +{ + + int proto = port->u.port.protocol; + int low = port->u.port.low_port; + int high = port->u.port.high_port; + context_struct_t *con = &port->context[0]; + int rec_proto = -1; + + sepol_context_t *tmp_con = NULL; + sepol_port_t *tmp_record = NULL; + + if (sepol_port_create(handle, &tmp_record) < 0) + goto err; + + rec_proto = ipproto2sepol(handle, proto); + if (rec_proto < 0) + goto err; + + sepol_port_set_proto(tmp_record, rec_proto); + sepol_port_set_range(tmp_record, low, high); + + if (context_to_record(handle, policydb, con, &tmp_con) < 0) + goto err; + + if (sepol_port_set_con(handle, tmp_record, tmp_con) < 0) + goto err; + + sepol_context_free(tmp_con); + *record = tmp_record; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not convert port range %u - %u (%s) " + "to record", low, high, sepol_port_get_proto_str(rec_proto)); + sepol_context_free(tmp_con); + sepol_port_free(tmp_record); + return STATUS_ERR; +} + +/* Return the number of ports */ +extern int sepol_port_count(sepol_handle_t * handle __attribute__ ((unused)), + const sepol_policydb_t * p, unsigned int *response) +{ + + unsigned int count = 0; + ocontext_t *c, *head; + const policydb_t *policydb = &p->p; + + head = policydb->ocontexts[OCON_PORT]; + for (c = head; c != NULL; c = c->next) + count++; + + *response = count; + + return STATUS_SUCCESS; +} + +/* Check if a port exists */ +int sepol_port_exists(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_port_key_t * key, int *response) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + + int low, high, proto; + const char *proto_str; + sepol_port_key_unpack(key, &low, &high, &proto); + proto_str = sepol_port_get_proto_str(proto); + proto = sepol2ipproto(handle, proto); + if (proto < 0) + goto err; + + head = policydb->ocontexts[OCON_PORT]; + for (c = head; c; c = c->next) { + int proto2 = c->u.port.protocol; + int low2 = c->u.port.low_port; + int high2 = c->u.port.high_port; + + if (proto == proto2 && low2 == low && high2 == high) { + *response = 1; + return STATUS_SUCCESS; + } + } + + *response = 0; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not check if port range %u - %u (%s) exists", + low, high, proto_str); + return STATUS_ERR; +} + +/* Query a port */ +int sepol_port_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_port_key_t * key, sepol_port_t ** response) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + + int low, high, proto; + const char *proto_str; + sepol_port_key_unpack(key, &low, &high, &proto); + proto_str = sepol_port_get_proto_str(proto); + proto = sepol2ipproto(handle, proto); + if (proto < 0) + goto err; + + head = policydb->ocontexts[OCON_PORT]; + for (c = head; c; c = c->next) { + int proto2 = c->u.port.protocol; + int low2 = c->u.port.low_port; + int high2 = c->u.port.high_port; + + if (proto == proto2 && low2 == low && high2 == high) { + if (port_to_record(handle, policydb, c, response) < 0) + goto err; + return STATUS_SUCCESS; + } + } + + *response = NULL; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not query port range %u - %u (%s)", + low, high, proto_str); + return STATUS_ERR; + +} + +/* Load a port into policy */ +int sepol_port_modify(sepol_handle_t * handle, + sepol_policydb_t * p, + const sepol_port_key_t * key, const sepol_port_t * data) +{ + + policydb_t *policydb = &p->p; + ocontext_t *port = NULL; + + int low, high, proto; + const char *proto_str; + + sepol_port_key_unpack(key, &low, &high, &proto); + proto_str = sepol_port_get_proto_str(proto); + proto = sepol2ipproto(handle, proto); + if (proto < 0) + goto err; + + if (port_from_record(handle, policydb, &port, data) < 0) + goto err; + + /* Attach to context list */ + port->next = policydb->ocontexts[OCON_PORT]; + policydb->ocontexts[OCON_PORT] = port; + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not load port range %u - %u (%s)", + low, high, proto_str); + if (port != NULL) { + context_destroy(&port->context[0]); + free(port); + } + return STATUS_ERR; +} + +int sepol_port_iterate(sepol_handle_t * handle, + const sepol_policydb_t * p, + int (*fn) (const sepol_port_t * port, + void *fn_arg), void *arg) +{ + + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + sepol_port_t *port = NULL; + + head = policydb->ocontexts[OCON_PORT]; + for (c = head; c; c = c->next) { + int status; + + if (port_to_record(handle, policydb, c, &port) < 0) + goto err; + + /* Invoke handler */ + status = fn(port, arg); + if (status < 0) + goto err; + + sepol_port_free(port); + port = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not iterate over ports"); + sepol_port_free(port); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/ports.o b/kernel/libsepol/src/ports.o new file mode 100644 index 00000000..e0e285c2 Binary files /dev/null and b/kernel/libsepol/src/ports.o differ diff --git a/kernel/libsepol/src/private.h b/kernel/libsepol/src/private.h new file mode 100644 index 00000000..87bbb550 --- /dev/null +++ b/kernel/libsepol/src/private.h @@ -0,0 +1,99 @@ +/* Private definitions for libsepol. */ + +/* Endian conversion for reading and writing binary policies */ + +#include + + +#ifdef __APPLE__ +#include +#include +#else +// #include +// #include +#endif + +// #include +#include + +#include "kernel.h" + +#ifdef __APPLE__ +#define __BYTE_ORDER BYTE_ORDER +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#endif + +// #if __BYTE_ORDER == __LITTLE_ENDIAN +// #define cpu_to_le16(x) (x) +// #define le16_to_cpu(x) (x) +// #define cpu_to_le32(x) (x) +// #define le32_to_cpu(x) (x) +// #define cpu_to_le64(x) (x) +// #define le64_to_cpu(x) (x) +// #else +// #define cpu_to_le16(x) bswap_16(x) +// #define le16_to_cpu(x) bswap_16(x) +// #define cpu_to_le32(x) bswap_32(x) +// #define le32_to_cpu(x) bswap_32(x) +// #define cpu_to_le64(x) bswap_64(x) +// #define le64_to_cpu(x) bswap_64(x) +// #endif + +#undef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) + +#undef max +#define max(a,b) ((a) >= (b) ? (a) : (b)) + +// #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +# define is_saturated(x) (x == (typeof(x))-1 || (x) > (1U << 16)) +#else +# define is_saturated(x) (x == (typeof(x))-1) +#endif + +#define zero_or_saturated(x) ((x == 0) || is_saturated(x)) + +#define spaceship_cmp(a, b) (((a) > (b)) - ((a) < (b))) + +/* Use to ignore intentional unsigned under- and overflows while running under UBSAN. */ +#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ >= 4) +#if (__clang_major__ >= 12) +#define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow", "unsigned-shift-base"))) +#else +#define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow"))) +#endif +#else +#define ignore_unsigned_overflow_ +#endif + +/* Policy compatibility information. */ +struct policydb_compat_info { + unsigned int type; + unsigned int version; + unsigned int sym_num; + unsigned int ocon_num; + unsigned int target_platform; +}; + +extern const struct policydb_compat_info *policydb_lookup_compat(unsigned int version, + unsigned int type, + unsigned int target_platform); + +/* Reading from a policy "file". */ +extern int next_entry(void *buf, struct policy_file *fp, size_t bytes); +extern size_t put_entry(const void *ptr, size_t size, size_t n, + struct policy_file *fp); +extern int str_read(char **strp, struct policy_file *fp, size_t len); + +#ifndef HAVE_REALLOCARRAY +static inline void* reallocarray(void *ptr, size_t nmemb, size_t size) { + if (size && nmemb > (size_t)-1 / size) { + // errno = ENOMEM; + return NULL; + } + + return realloc(ptr, nmemb * size); +} +#endif diff --git a/kernel/libsepol/src/services.c b/kernel/libsepol/src/services.c new file mode 100644 index 00000000..40bae0e9 --- /dev/null +++ b/kernel/libsepol/src/services.c @@ -0,0 +1,2327 @@ +/* + * Author : Stephen Smalley, + */ +/* + * Updated: Trusted Computer Solutions, Inc. + * + * Support for enhanced MLS infrastructure. + * + * Updated: Frank Mayer + * and Karl MacMillan + * + * Added conditional policy language extensions + * + * Updated: Red Hat, Inc. James Morris + * + * Fine-grained netlink support + * IPv6 support + * Code cleanup + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2003 - 2004 Tresys Technology, LLC + * Copyright (C) 2003 - 2004 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Technologies Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* FLASK */ + +/* + * Implementation of the security services. + */ + +/* Initial sizes malloc'd for sepol_compute_av_reason_buffer() support */ +#define REASON_BUF_SIZE 2048 +#define EXPR_BUF_SIZE 1024 +#define STACK_LEN 32 + +// #include +#include +#include +// #include +#include +// #include +#include + +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "private.h" +#include "context.h" +#include "mls.h" +#include "flask.h" + +#ifndef BUG +#define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) +#endif + +static int selinux_enforcing = 1; + +static sidtab_t mysidtab, *sidtab = &mysidtab; +static policydb_t mypolicydb, *policydb = &mypolicydb; + +/* Used by sepol_compute_av_reason_buffer() to keep track of entries */ +static int reason_buf_used; +static int reason_buf_len; + +/* Stack services for RPN to infix conversion. */ +static char **stack; +static int stack_len; +static int next_stack_entry; + +static void push(char *expr_ptr) +{ + if (next_stack_entry >= stack_len) { + char **new_stack; + int new_stack_len; + + if (stack_len == 0) + new_stack_len = STACK_LEN; + else + new_stack_len = stack_len * 2; + + new_stack = reallocarray(stack, new_stack_len, sizeof(*stack)); + if (!new_stack) { + ERR(NULL, "unable to allocate stack space"); + return; + } + stack_len = new_stack_len; + stack = new_stack; + } + stack[next_stack_entry] = expr_ptr; + next_stack_entry++; +} + +static char *pop(void) +{ + next_stack_entry--; + if (next_stack_entry < 0) { + next_stack_entry = 0; + ERR(NULL, "pop called with no stack entries"); + return NULL; + } + return stack[next_stack_entry]; +} +/* End Stack services */ + +int sepol_set_sidtab(sidtab_t * s) +{ + sidtab = s; + return 0; +} + +int sepol_set_policydb(policydb_t * p) +{ + policydb = p; + return 0; +} + +int sepol_set_policydb_from_file(FILE * fp) +{ + struct policy_file pf; + + policy_file_init(&pf); + pf.fp = fp; + pf.type = PF_USE_STDIO; + if (mypolicydb.policy_type) + ksu_policydb_destroy(&mypolicydb); + if (policydb_init(&mypolicydb)) { + ERR(NULL, "Out of memory!"); + return -1; + } + if (ksu_policydb_read(&mypolicydb, &pf, 0)) { + ksu_policydb_destroy(&mypolicydb); + ERR(NULL, "can't read binary policy: %m"); + return -1; + } + policydb = &mypolicydb; + return sepol_sidtab_init(sidtab); +} + +/* + * The largest sequence number that has been used when + * providing an access decision to the access vector cache. + * The sequence number only changes when a policy change + * occurs. + */ +static uint32_t latest_granting = 0; + +/* + * cat_expr_buf adds a string to an expression buffer and handles + * realloc's if buffer is too small. The array of expression text + * buffer pointers and its counter are globally defined here as + * constraint_expr_eval_reason() sets them up and cat_expr_buf + * updates the e_buf pointer. + */ +static int expr_counter; +static char **expr_list; +static int expr_buf_used; +static int expr_buf_len; + +static void cat_expr_buf(char *e_buf, const char *string) +{ + int len, new_buf_len; + char *p, *new_buf; + + while (1) { + p = e_buf + expr_buf_used; + len = snprintf(p, expr_buf_len - expr_buf_used, "%s", string); + if (len < 0 || len >= expr_buf_len - expr_buf_used) { + new_buf_len = expr_buf_len + EXPR_BUF_SIZE; + new_buf = realloc(e_buf, new_buf_len); + if (!new_buf) { + ERR(NULL, "failed to realloc expr buffer"); + return; + } + /* Update new ptr in expr list and locally + new len */ + expr_list[expr_counter] = new_buf; + e_buf = new_buf; + expr_buf_len = new_buf_len; + } else { + expr_buf_used += len; + return; + } + } +} + +/* + * If the POLICY_KERN version is >= POLICYDB_VERSION_CONSTRAINT_NAMES, + * then for 'types' only, read the types_names->types list as it will + * contain a list of types and attributes that were defined in the + * policy source. + * For user and role plus types (for policy vers < + * POLICYDB_VERSION_CONSTRAINT_NAMES) just read the e->names list. + */ +static void get_name_list(constraint_expr_t *e, int type, + const char *src, const char *op, int failed) +{ + ebitmap_t *types; + int rc = 0; + unsigned int i; + char tmp_buf[128]; + int counter = 0; + + if (policydb->policy_type == POLICY_KERN && + policydb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES && + type == CEXPR_TYPE) + types = &e->type_names->types; + else + types = &e->names; + + /* Find out how many entries */ + for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) { + rc = ksu_ebitmap_get_bit(types, i); + if (rc == 0) + continue; + else + counter++; + } + snprintf(tmp_buf, sizeof(tmp_buf), "(%s%s", src, op); + cat_expr_buf(expr_list[expr_counter], tmp_buf); + + if (counter == 0) + cat_expr_buf(expr_list[expr_counter], " "); + if (counter > 1) + cat_expr_buf(expr_list[expr_counter], " {"); + if (counter >= 1) { + for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) { + rc = ksu_ebitmap_get_bit(types, i); + if (rc == 0) + continue; + + /* Collect entries */ + switch (type) { + case CEXPR_USER: + snprintf(tmp_buf, sizeof(tmp_buf), " %s", + policydb->p_user_val_to_name[i]); + break; + case CEXPR_ROLE: + snprintf(tmp_buf, sizeof(tmp_buf), " %s", + policydb->p_role_val_to_name[i]); + break; + case CEXPR_TYPE: + snprintf(tmp_buf, sizeof(tmp_buf), " %s", + policydb->p_type_val_to_name[i]); + break; + } + cat_expr_buf(expr_list[expr_counter], tmp_buf); + } + } + if (counter > 1) + cat_expr_buf(expr_list[expr_counter], " }"); + if (failed) + cat_expr_buf(expr_list[expr_counter], " -Fail-) "); + else + cat_expr_buf(expr_list[expr_counter], ") "); + + return; +} + +static void msgcat(const char *src, const char *tgt, const char *op, int failed) +{ + char tmp_buf[128]; + if (failed) + snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s -Fail-) ", + src, op, tgt); + else + snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s) ", + src, op, tgt); + cat_expr_buf(expr_list[expr_counter], tmp_buf); +} + +/* Returns a buffer with class, statement type and permissions */ +static char *get_class_info(sepol_security_class_t tclass, + constraint_node_t *constraint, + context_struct_t *xcontext) +{ + constraint_expr_t *e; + int mls, state_num; + /* Determine statement type */ + const char *statements[] = { + "constrain ", /* 0 */ + "mlsconstrain ", /* 1 */ + "validatetrans ", /* 2 */ + "mlsvalidatetrans ", /* 3 */ + 0 }; + size_t class_buf_len = 0; + size_t new_class_buf_len; + size_t buf_used; + int len; + char *class_buf = NULL, *p; + char *new_class_buf = NULL; + + /* Find if MLS statement or not */ + mls = 0; + for (e = constraint->expr; e; e = e->next) { + if (e->attr >= CEXPR_L1L2) { + mls = 1; + break; + } + } + + if (xcontext == NULL) + state_num = mls + 0; + else + state_num = mls + 2; + + while (1) { + new_class_buf_len = class_buf_len + EXPR_BUF_SIZE; + new_class_buf = realloc(class_buf, new_class_buf_len); + if (!new_class_buf) { + free(class_buf); + return NULL; + } + class_buf_len = new_class_buf_len; + class_buf = new_class_buf; + buf_used = 0; + p = class_buf; + + /* Add statement type */ + len = snprintf(p, class_buf_len - buf_used, "%s", statements[state_num]); + if (len < 0 || (size_t)len >= class_buf_len - buf_used) + continue; + + /* Add class entry */ + p += len; + buf_used += len; + len = snprintf(p, class_buf_len - buf_used, "%s ", + policydb->p_class_val_to_name[tclass - 1]); + if (len < 0 || (size_t)len >= class_buf_len - buf_used) + continue; + + /* Add permission entries (validatetrans does not have perms) */ + p += len; + buf_used += len; + if (state_num < 2) { + len = snprintf(p, class_buf_len - buf_used, "{%s } (", + sepol_av_to_string(policydb, tclass, + constraint->permissions)); + } else { + len = snprintf(p, class_buf_len - buf_used, "("); + } + if (len < 0 || (size_t)len >= class_buf_len - buf_used) + continue; + break; + } + return class_buf; +} + +/* + * Modified version of constraint_expr_eval that will process each + * constraint as before but adds the information to text buffers that + * will hold various components. The expression will be in RPN format, + * therefore there is a stack based RPN to infix converter to produce + * the final readable constraint. + * + * Return the boolean value of a constraint expression + * when it is applied to the specified source and target + * security contexts. + * + * xcontext is a special beast... It is used by the validatetrans rules + * only. For these rules, scontext is the context before the transition, + * tcontext is the context after the transition, and xcontext is the + * context of the process performing the transition. All other callers + * of constraint_expr_eval_reason should pass in NULL for xcontext. + * + * This function will also build a buffer as the constraint is processed + * for analysis. If this option is not required, then: + * 'tclass' should be '0' and r_buf MUST be NULL. + */ +static int constraint_expr_eval_reason(context_struct_t *scontext, + context_struct_t *tcontext, + context_struct_t *xcontext, + sepol_security_class_t tclass, + constraint_node_t *constraint, + char **r_buf, + unsigned int flags) +{ + uint32_t val1, val2; + context_struct_t *c; + role_datum_t *r1, *r2; + mls_level_t *l1, *l2; + constraint_expr_t *e; + int s[CEXPR_MAXDEPTH]; + int sp = -1; + char tmp_buf[128]; + +/* + * Define the s_t_x_num values that make up r1, t2 etc. in text strings + * Set 1 = source, 2 = target, 3 = xcontext for validatetrans + */ +#define SOURCE 1 +#define TARGET 2 +#define XTARGET 3 + + int s_t_x_num; + + /* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */ + int u_r_t = 0; + + char *src = NULL; + char *tgt = NULL; + int rc = 0, x; + char *class_buf = NULL; + int expr_list_len = 0; + int expr_count; + + /* + * The array of expression answer buffer pointers and counter. + */ + char **answer_list = NULL; + int answer_counter = 0; + + /* The pop operands */ + char *a; + char *b; + int a_len, b_len; + + class_buf = get_class_info(tclass, constraint, xcontext); + if (!class_buf) { + ERR(NULL, "failed to allocate class buffer"); + return -ENOMEM; + } + + /* Original function but with buffer support */ + expr_counter = 0; + expr_list = NULL; + for (e = constraint->expr; e; e = e->next) { + /* Allocate a stack to hold expression buffer entries */ + if (expr_counter >= expr_list_len) { + char **new_expr_list; + int new_expr_list_len; + + if (expr_list_len == 0) + new_expr_list_len = STACK_LEN; + else + new_expr_list_len = expr_list_len * 2; + + new_expr_list = reallocarray(expr_list, + new_expr_list_len, sizeof(*expr_list)); + if (!new_expr_list) { + ERR(NULL, "failed to allocate expr buffer stack"); + rc = -ENOMEM; + goto out; + } + expr_list_len = new_expr_list_len; + expr_list = new_expr_list; + } + + /* + * malloc a buffer to store each expression text component. If + * buffer is too small cat_expr_buf() will realloc extra space. + */ + expr_buf_len = EXPR_BUF_SIZE; + expr_list[expr_counter] = malloc(expr_buf_len); + if (!expr_list[expr_counter]) { + ERR(NULL, "failed to allocate expr buffer"); + rc = -ENOMEM; + goto out; + } + expr_buf_used = 0; + + /* Now process each expression of the constraint */ + switch (e->expr_type) { + case CEXPR_NOT: + if (sp < 0) { + BUG(); + rc = -EINVAL; + goto out; + } + s[sp] = !s[sp]; + cat_expr_buf(expr_list[expr_counter], "not"); + break; + case CEXPR_AND: + if (sp < 1) { + BUG(); + rc = -EINVAL; + goto out; + } + sp--; + s[sp] &= s[sp + 1]; + cat_expr_buf(expr_list[expr_counter], "and"); + break; + case CEXPR_OR: + if (sp < 1) { + BUG(); + rc = -EINVAL; + goto out; + } + sp--; + s[sp] |= s[sp + 1]; + cat_expr_buf(expr_list[expr_counter], "or"); + break; + case CEXPR_ATTR: + if (sp == (CEXPR_MAXDEPTH - 1)) + goto out; + + switch (e->attr) { + case CEXPR_USER: + val1 = scontext->user; + val2 = tcontext->user; + free(src); src = strdup("u1"); + free(tgt); tgt = strdup("u2"); + break; + case CEXPR_TYPE: + val1 = scontext->type; + val2 = tcontext->type; + free(src); src = strdup("t1"); + free(tgt); tgt = strdup("t2"); + break; + case CEXPR_ROLE: + val1 = scontext->role; + val2 = tcontext->role; + r1 = policydb->role_val_to_struct[val1 - 1]; + r2 = policydb->role_val_to_struct[val2 - 1]; + free(src); src = strdup("r1"); + free(tgt); tgt = strdup("r2"); + + switch (e->op) { + case CEXPR_DOM: + s[++sp] = ksu_ebitmap_get_bit(&r1->dominates, val2 - 1); + msgcat(src, tgt, "dom", s[sp] == 0); + expr_counter++; + continue; + case CEXPR_DOMBY: + s[++sp] = ksu_ebitmap_get_bit(&r2->dominates, val1 - 1); + msgcat(src, tgt, "domby", s[sp] == 0); + expr_counter++; + continue; + case CEXPR_INCOMP: + s[++sp] = (!ksu_ebitmap_get_bit(&r1->dominates, val2 - 1) + && !ksu_ebitmap_get_bit(&r2->dominates, val1 - 1)); + msgcat(src, tgt, "incomp", s[sp] == 0); + expr_counter++; + continue; + default: + break; + } + break; + case CEXPR_L1L2: + l1 = &(scontext->range.level[0]); + l2 = &(tcontext->range.level[0]); + free(src); src = strdup("l1"); + free(tgt); tgt = strdup("l2"); + goto mls_ops; + case CEXPR_L1H2: + l1 = &(scontext->range.level[0]); + l2 = &(tcontext->range.level[1]); + free(src); src = strdup("l1"); + free(tgt); tgt = strdup("h2"); + goto mls_ops; + case CEXPR_H1L2: + l1 = &(scontext->range.level[1]); + l2 = &(tcontext->range.level[0]); + free(src); src = strdup("h1"); + free(tgt); tgt = strdup("l2"); + goto mls_ops; + case CEXPR_H1H2: + l1 = &(scontext->range.level[1]); + l2 = &(tcontext->range.level[1]); + free(src); src = strdup("h1"); + free(tgt); tgt = strdup("h2"); + goto mls_ops; + case CEXPR_L1H1: + l1 = &(scontext->range.level[0]); + l2 = &(scontext->range.level[1]); + free(src); src = strdup("l1"); + free(tgt); tgt = strdup("h1"); + goto mls_ops; + case CEXPR_L2H2: + l1 = &(tcontext->range.level[0]); + l2 = &(tcontext->range.level[1]); + free(src); src = strdup("l2"); + free(tgt); tgt = strdup("h2"); +mls_ops: + switch (e->op) { + case CEXPR_EQ: + s[++sp] = mls_level_eq(l1, l2); + msgcat(src, tgt, "eq", s[sp] == 0); + expr_counter++; + continue; + case CEXPR_NEQ: + s[++sp] = !mls_level_eq(l1, l2); + msgcat(src, tgt, "!=", s[sp] == 0); + expr_counter++; + continue; + case CEXPR_DOM: + s[++sp] = mls_level_dom(l1, l2); + msgcat(src, tgt, "dom", s[sp] == 0); + expr_counter++; + continue; + case CEXPR_DOMBY: + s[++sp] = mls_level_dom(l2, l1); + msgcat(src, tgt, "domby", s[sp] == 0); + expr_counter++; + continue; + case CEXPR_INCOMP: + s[++sp] = mls_level_incomp(l2, l1); + msgcat(src, tgt, "incomp", s[sp] == 0); + expr_counter++; + continue; + default: + BUG(); + goto out; + } + break; + default: + BUG(); + goto out; + } + + switch (e->op) { + case CEXPR_EQ: + s[++sp] = (val1 == val2); + msgcat(src, tgt, "==", s[sp] == 0); + break; + case CEXPR_NEQ: + s[++sp] = (val1 != val2); + msgcat(src, tgt, "!=", s[sp] == 0); + break; + default: + BUG(); + goto out; + } + break; + case CEXPR_NAMES: + if (sp == (CEXPR_MAXDEPTH - 1)) + goto out; + s_t_x_num = SOURCE; + c = scontext; + if (e->attr & CEXPR_TARGET) { + s_t_x_num = TARGET; + c = tcontext; + } else if (e->attr & CEXPR_XTARGET) { + s_t_x_num = XTARGET; + c = xcontext; + } + if (!c) { + BUG(); + goto out; + } + if (e->attr & CEXPR_USER) { + u_r_t = CEXPR_USER; + val1 = c->user; + snprintf(tmp_buf, sizeof(tmp_buf), "u%d ", s_t_x_num); + free(src); src = strdup(tmp_buf); + } else if (e->attr & CEXPR_ROLE) { + u_r_t = CEXPR_ROLE; + val1 = c->role; + snprintf(tmp_buf, sizeof(tmp_buf), "r%d ", s_t_x_num); + free(src); src = strdup(tmp_buf); + } else if (e->attr & CEXPR_TYPE) { + u_r_t = CEXPR_TYPE; + val1 = c->type; + snprintf(tmp_buf, sizeof(tmp_buf), "t%d ", s_t_x_num); + free(src); src = strdup(tmp_buf); + } else { + BUG(); + goto out; + } + + switch (e->op) { + case CEXPR_EQ: + s[++sp] = ksu_ebitmap_get_bit(&e->names, val1 - 1); + get_name_list(e, u_r_t, src, "==", s[sp] == 0); + break; + + case CEXPR_NEQ: + s[++sp] = !ksu_ebitmap_get_bit(&e->names, val1 - 1); + get_name_list(e, u_r_t, src, "!=", s[sp] == 0); + break; + default: + BUG(); + goto out; + } + break; + default: + BUG(); + goto out; + } + expr_counter++; + } + + /* + * At this point each expression of the constraint is in + * expr_list[n+1] and in RPN format. Now convert to 'infix' + */ + + /* + * Save expr count but zero expr_counter to detect if + * 'BUG(); goto out;' was called as we need to release any used + * expr_list malloc's. Normally they are released by the RPN to + * infix code. + */ + expr_count = expr_counter; + expr_counter = 0; + + /* + * Generate the same number of answer buffer entries as expression + * buffers (as there will never be more). + */ + answer_list = calloc(expr_count, sizeof(*answer_list)); + if (!answer_list) { + ERR(NULL, "failed to allocate answer stack"); + rc = -ENOMEM; + goto out; + } + + /* Convert constraint from RPN to infix notation. */ + for (x = 0; x != expr_count; x++) { + if (strncmp(expr_list[x], "and", 3) == 0 || strncmp(expr_list[x], + "or", 2) == 0) { + b = pop(); + b_len = strlen(b); + a = pop(); + a_len = strlen(a); + + /* get a buffer to hold the answer */ + answer_list[answer_counter] = malloc(a_len + b_len + 8); + if (!answer_list[answer_counter]) { + ERR(NULL, "failed to allocate answer buffer"); + rc = -ENOMEM; + goto out; + } + memset(answer_list[answer_counter], '\0', a_len + b_len + 8); + + sprintf(answer_list[answer_counter], "%s %s %s", a, + expr_list[x], b); + push(answer_list[answer_counter++]); + free(a); + free(b); + free(expr_list[x]); + } else if (strncmp(expr_list[x], "not", 3) == 0) { + b = pop(); + b_len = strlen(b); + + answer_list[answer_counter] = malloc(b_len + 8); + if (!answer_list[answer_counter]) { + ERR(NULL, "failed to allocate answer buffer"); + rc = -ENOMEM; + goto out; + } + memset(answer_list[answer_counter], '\0', b_len + 8); + + if (strncmp(b, "not", 3) == 0) + sprintf(answer_list[answer_counter], "%s (%s)", + expr_list[x], b); + else + sprintf(answer_list[answer_counter], "%s%s", + expr_list[x], b); + push(answer_list[answer_counter++]); + free(b); + free(expr_list[x]); + } else { + push(expr_list[x]); + } + } + /* Get the final answer from tos and build constraint text */ + a = pop(); + + /* validatetrans / constraint calculation: + rc = 0 is denied, rc = 1 is granted */ + sprintf(tmp_buf, "%s %s\n", + xcontext ? "Validatetrans" : "Constraint", + s[0] ? "GRANTED" : "DENIED"); + + /* + * This will add the constraints to the callers reason buffer (who is + * responsible for freeing the memory). It will handle any realloc's + * should the buffer be too short. + * The reason_buf_used and reason_buf_len counters are defined + * globally as multiple constraints can be in the buffer. + */ + + if (r_buf && ((s[0] == 0) || ((s[0] == 1 && + (flags & SHOW_GRANTED) == SHOW_GRANTED)))) { + int len, new_buf_len; + char *p, **new_buf = r_buf; + /* + * These contain the constraint components that are added to the + * callers reason buffer. + */ + const char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 }; + + for (x = 0; buffers[x] != NULL; x++) { + while (1) { + p = *r_buf ? (*r_buf + reason_buf_used) : NULL; + len = snprintf(p, reason_buf_len - reason_buf_used, + "%s", buffers[x]); + if (len < 0 || len >= reason_buf_len - reason_buf_used) { + new_buf_len = reason_buf_len + REASON_BUF_SIZE; + *new_buf = realloc(*r_buf, new_buf_len); + if (!*new_buf) { + ERR(NULL, "failed to realloc reason buffer"); + goto out1; + } + **r_buf = **new_buf; + reason_buf_len = new_buf_len; + continue; + } else { + reason_buf_used += len; + break; + } + } + } + } + +out1: + rc = s[0]; + free(a); + +out: + free(class_buf); + free(src); + free(tgt); + + if (expr_counter) { + for (x = 0; expr_list[x] != NULL; x++) + free(expr_list[x]); + } + free(answer_list); + free(expr_list); + return rc; +} + +/* Forward declaration */ +static int context_struct_compute_av(context_struct_t * scontext, + context_struct_t * tcontext, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason, + char **r_buf, + unsigned int flags); + +static void type_attribute_bounds_av(context_struct_t *scontext, + context_struct_t *tcontext, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason) +{ + context_struct_t lo_scontext; + context_struct_t lo_tcontext, *tcontextp = tcontext; + struct sepol_av_decision lo_avd; + type_datum_t *source; + type_datum_t *target; + sepol_access_vector_t masked = 0; + + source = policydb->type_val_to_struct[scontext->type - 1]; + if (!source->bounds) + return; + + target = policydb->type_val_to_struct[tcontext->type - 1]; + + memset(&lo_avd, 0, sizeof(lo_avd)); + + memcpy(&lo_scontext, scontext, sizeof(lo_scontext)); + lo_scontext.type = source->bounds; + + if (target->bounds) { + memcpy(&lo_tcontext, tcontext, sizeof(lo_tcontext)); + lo_tcontext.type = target->bounds; + tcontextp = &lo_tcontext; + } + + context_struct_compute_av(&lo_scontext, + tcontextp, + tclass, + requested, + &lo_avd, + NULL, /* reason intentionally omitted */ + NULL, + 0); + + masked = ~lo_avd.allowed & avd->allowed; + + if (!masked) + return; /* no masked permission */ + + /* mask violated permissions */ + avd->allowed &= ~masked; + + *reason |= SEPOL_COMPUTEAV_BOUNDS; +} + +/* + * Compute access vectors based on a context structure pair for + * the permissions in a particular class. + */ +static int context_struct_compute_av(context_struct_t * scontext, + context_struct_t * tcontext, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason, + char **r_buf, + unsigned int flags) +{ + constraint_node_t *constraint; + struct role_allow *ra; + avtab_key_t avkey; + class_datum_t *tclass_datum; + avtab_ptr_t node; + ebitmap_t *sattr, *tattr; + ebitmap_node_t *snode, *tnode; + unsigned int i, j; + + if (!tclass || tclass > policydb->p_classes.nprim) { + ERR(NULL, "unrecognized class %d", tclass); + return -EINVAL; + } + tclass_datum = policydb->class_val_to_struct[tclass - 1]; + + /* + * Initialize the access vectors to the default values. + */ + avd->allowed = 0; + avd->decided = 0xffffffff; + avd->auditallow = 0; + avd->auditdeny = 0xffffffff; + avd->seqno = latest_granting; + if (reason) + *reason = 0; + + /* + * If a specific type enforcement rule was defined for + * this permission check, then use it. + */ + avkey.target_class = tclass; + avkey.specified = AVTAB_AV; + sattr = &policydb->type_attr_map[scontext->type - 1]; + tattr = &policydb->type_attr_map[tcontext->type - 1]; + ebitmap_for_each_positive_bit(sattr, snode, i) { + ebitmap_for_each_positive_bit(tattr, tnode, j) { + avkey.source_type = i + 1; + avkey.target_type = j + 1; + for (node = + ksu_avtab_search_node(&policydb->te_avtab, &avkey); + node != NULL; + node = + ksu_avtab_search_node_next(node, avkey.specified)) { + if (node->key.specified == AVTAB_ALLOWED) + avd->allowed |= node->datum.data; + else if (node->key.specified == + AVTAB_AUDITALLOW) + avd->auditallow |= node->datum.data; + else if (node->key.specified == AVTAB_AUDITDENY) + avd->auditdeny &= node->datum.data; + } + + /* Check conditional av table for additional permissions */ + ksu_cond_compute_av(&policydb->te_cond_avtab, &avkey, avd); + + } + } + + if (requested & ~avd->allowed) { + if (reason) + *reason |= SEPOL_COMPUTEAV_TE; + requested &= avd->allowed; + } + + /* + * Remove any permissions prohibited by a constraint (this includes + * the MLS policy). + */ + constraint = tclass_datum->constraints; + while (constraint) { + if ((constraint->permissions & (avd->allowed)) && + !constraint_expr_eval_reason(scontext, tcontext, NULL, + tclass, constraint, r_buf, flags)) { + avd->allowed = + (avd->allowed) & ~(constraint->permissions); + } + constraint = constraint->next; + } + + if (requested & ~avd->allowed) { + if (reason) + *reason |= SEPOL_COMPUTEAV_CONS; + requested &= avd->allowed; + } + + /* + * If checking process transition permission and the + * role is changing, then check the (current_role, new_role) + * pair. + */ + if (tclass == policydb->process_class && + (avd->allowed & policydb->process_trans_dyntrans) && + scontext->role != tcontext->role) { + for (ra = policydb->role_allow; ra; ra = ra->next) { + if (scontext->role == ra->role && + tcontext->role == ra->new_role) + break; + } + if (!ra) + avd->allowed &= ~policydb->process_trans_dyntrans; + } + + if (requested & ~avd->allowed) { + if (reason) + *reason |= SEPOL_COMPUTEAV_RBAC; + requested &= avd->allowed; + } + + type_attribute_bounds_av(scontext, tcontext, tclass, requested, avd, + reason); + return 0; +} + +/* + * sepol_validate_transition_reason_buffer - the reason buffer is realloc'd + * in the constraint_expr_eval_reason() function. + */ +int sepol_validate_transition_reason_buffer(sepol_security_id_t oldsid, + sepol_security_id_t newsid, + sepol_security_id_t tasksid, + sepol_security_class_t tclass, + char **reason_buf, + unsigned int flags) +{ + context_struct_t *ocontext; + context_struct_t *ncontext; + context_struct_t *tcontext; + class_datum_t *tclass_datum; + constraint_node_t *constraint; + + if (!tclass || tclass > policydb->p_classes.nprim) { + ERR(NULL, "unrecognized class %d", tclass); + return -EINVAL; + } + tclass_datum = policydb->class_val_to_struct[tclass - 1]; + + ocontext = sepol_sidtab_search(sidtab, oldsid); + if (!ocontext) { + ERR(NULL, "unrecognized SID %d", oldsid); + return -EINVAL; + } + + ncontext = sepol_sidtab_search(sidtab, newsid); + if (!ncontext) { + ERR(NULL, "unrecognized SID %d", newsid); + return -EINVAL; + } + + tcontext = sepol_sidtab_search(sidtab, tasksid); + if (!tcontext) { + ERR(NULL, "unrecognized SID %d", tasksid); + return -EINVAL; + } + + /* + * Set the buffer to NULL as mls/validatetrans may not be processed. + * If a buffer is required, then the routines in + * constraint_expr_eval_reason will realloc in REASON_BUF_SIZE + * chunks (as it gets called for each mls/validatetrans processed). + * We just make sure these start from zero. + */ + *reason_buf = NULL; + reason_buf_used = 0; + reason_buf_len = 0; + constraint = tclass_datum->validatetrans; + while (constraint) { + if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext, + tclass, constraint, reason_buf, flags)) { + return -EPERM; + } + constraint = constraint->next; + } + return 0; +} + +int sepol_compute_av_reason(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason) +{ + context_struct_t *scontext = 0, *tcontext = 0; + int rc = 0; + + scontext = sepol_sidtab_search(sidtab, ssid); + if (!scontext) { + ERR(NULL, "unrecognized source SID %d", ssid); + rc = -EINVAL; + goto out; + } + tcontext = sepol_sidtab_search(sidtab, tsid); + if (!tcontext) { + ERR(NULL, "unrecognized target SID %d", tsid); + rc = -EINVAL; + goto out; + } + + rc = context_struct_compute_av(scontext, tcontext, tclass, + requested, avd, reason, NULL, 0); + out: + return rc; +} + +/* + * sepol_compute_av_reason_buffer - the reason buffer is malloc'd to + * REASON_BUF_SIZE. If the buffer size is exceeded, then it is realloc'd + * in the constraint_expr_eval_reason() function. + */ +int sepol_compute_av_reason_buffer(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd, + unsigned int *reason, + char **reason_buf, + unsigned int flags) +{ + context_struct_t *scontext = 0, *tcontext = 0; + int rc = 0; + + scontext = sepol_sidtab_search(sidtab, ssid); + if (!scontext) { + ERR(NULL, "unrecognized source SID %d", ssid); + rc = -EINVAL; + goto out; + } + tcontext = sepol_sidtab_search(sidtab, tsid); + if (!tcontext) { + ERR(NULL, "unrecognized target SID %d", tsid); + rc = -EINVAL; + goto out; + } + + /* + * Set the buffer to NULL as constraints may not be processed. + * If a buffer is required, then the routines in + * constraint_expr_eval_reason will realloc in REASON_BUF_SIZE + * chunks (as it gets called for each constraint processed). + * We just make sure these start from zero. + */ + *reason_buf = NULL; + reason_buf_used = 0; + reason_buf_len = 0; + + rc = context_struct_compute_av(scontext, tcontext, tclass, + requested, avd, reason, reason_buf, flags); +out: + return rc; +} + +int sepol_compute_av(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_access_vector_t requested, + struct sepol_av_decision *avd) +{ + unsigned int reason = 0; + return sepol_compute_av_reason(ssid, tsid, tclass, requested, avd, + &reason); +} + +/* + * Return a class ID associated with the class string specified by + * class_name. + */ +int sepol_string_to_security_class(const char *class_name, + sepol_security_class_t *tclass) +{ + class_datum_t *tclass_datum; + + tclass_datum = hashtab_search(policydb->p_classes.table, + class_name); + if (!tclass_datum) { + ERR(NULL, "unrecognized class %s", class_name); + return STATUS_ERR; + } + *tclass = tclass_datum->s.value; + return STATUS_SUCCESS; +} + +/* + * Return access vector bit associated with the class ID and permission + * string. + */ +int sepol_string_to_av_perm(sepol_security_class_t tclass, + const char *perm_name, + sepol_access_vector_t *av) +{ + class_datum_t *tclass_datum; + perm_datum_t *perm_datum; + + if (!tclass || tclass > policydb->p_classes.nprim) { + ERR(NULL, "unrecognized class %d", tclass); + return -EINVAL; + } + tclass_datum = policydb->class_val_to_struct[tclass - 1]; + + /* Check for unique perms then the common ones (if any) */ + perm_datum = (perm_datum_t *) + hashtab_search(tclass_datum->permissions.table, + perm_name); + if (perm_datum != NULL) { + *av = UINT32_C(1) << (perm_datum->s.value - 1); + return STATUS_SUCCESS; + } + + if (tclass_datum->comdatum == NULL) + goto out; + + perm_datum = (perm_datum_t *) + hashtab_search(tclass_datum->comdatum->permissions.table, + perm_name); + + if (perm_datum != NULL) { + *av = UINT32_C(1) << (perm_datum->s.value - 1); + return STATUS_SUCCESS; + } +out: + ERR(NULL, "could not convert %s to av bit", perm_name); + return STATUS_ERR; +} + + const char *sepol_av_perm_to_string(sepol_security_class_t tclass, + sepol_access_vector_t av) +{ + return sepol_av_to_string(policydb, tclass, av); +} + +/* + * Write the security context string representation of + * the context associated with `sid' into a dynamically + * allocated string of the correct size. Set `*scontext' + * to point to this string and set `*scontext_len' to + * the length of the string. + */ +int sepol_sid_to_context(sepol_security_id_t sid, + sepol_security_context_t * scontext, + size_t * scontext_len) +{ + context_struct_t *context; + int rc = 0; + + context = sepol_sidtab_search(sidtab, sid); + if (!context) { + ERR(NULL, "unrecognized SID %d", sid); + rc = -EINVAL; + goto out; + } + rc = context_to_string(NULL, policydb, context, scontext, scontext_len); + out: + return rc; + +} + +/* + * Return a SID associated with the security context that + * has the string representation specified by `scontext'. + */ +int sepol_context_to_sid(sepol_const_security_context_t scontext, + size_t scontext_len, sepol_security_id_t * sid) +{ + + context_struct_t *context = NULL; + + /* First, create the context */ + if (context_from_string(NULL, policydb, &context, + scontext, scontext_len) < 0) + goto err; + + /* Obtain the new sid */ + if (sid && (sepol_sidtab_context_to_sid(sidtab, context, sid) < 0)) + goto err; + + context_destroy(context); + free(context); + return STATUS_SUCCESS; + + err: + if (context) { + context_destroy(context); + free(context); + } + ERR(NULL, "could not convert %s to sid", scontext); + return STATUS_ERR; +} + +static inline int compute_sid_handle_invalid_context(context_struct_t * + scontext, + context_struct_t * + tcontext, + sepol_security_class_t + tclass, + context_struct_t * + newcontext) +{ + if (selinux_enforcing) { + return -EACCES; + } else { + sepol_security_context_t s, t, n; + size_t slen, tlen, nlen; + + context_to_string(NULL, policydb, scontext, &s, &slen); + context_to_string(NULL, policydb, tcontext, &t, &tlen); + context_to_string(NULL, policydb, newcontext, &n, &nlen); + ERR(NULL, "invalid context %s for " + "scontext=%s tcontext=%s tclass=%s", + n, s, t, policydb->p_class_val_to_name[tclass - 1]); + free(s); + free(t); + free(n); + return 0; + } +} + +static int sepol_compute_sid(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + uint32_t specified, sepol_security_id_t * out_sid) +{ + struct class_datum *cladatum = NULL; + context_struct_t *scontext = 0, *tcontext = 0, newcontext; + struct role_trans *roletr = 0; + avtab_key_t avkey; + avtab_datum_t *avdatum; + avtab_ptr_t node; + int rc = 0; + + scontext = sepol_sidtab_search(sidtab, ssid); + if (!scontext) { + ERR(NULL, "unrecognized SID %d", ssid); + rc = -EINVAL; + goto out; + } + tcontext = sepol_sidtab_search(sidtab, tsid); + if (!tcontext) { + ERR(NULL, "unrecognized SID %d", tsid); + rc = -EINVAL; + goto out; + } + + if (tclass && tclass <= policydb->p_classes.nprim) + cladatum = policydb->class_val_to_struct[tclass - 1]; + + context_init(&newcontext); + + /* Set the user identity. */ + switch (specified) { + case AVTAB_TRANSITION: + case AVTAB_CHANGE: + if (cladatum && cladatum->default_user == DEFAULT_TARGET) { + newcontext.user = tcontext->user; + } else { + /* notice this gets both DEFAULT_SOURCE and unset */ + /* Use the process user identity. */ + newcontext.user = scontext->user; + } + break; + case AVTAB_MEMBER: + /* Use the related object owner. */ + newcontext.user = tcontext->user; + break; + } + + /* Set the role to default values. */ + if (cladatum && cladatum->default_role == DEFAULT_SOURCE) { + newcontext.role = scontext->role; + } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { + newcontext.role = tcontext->role; + } else { + if (tclass == policydb->process_class) + newcontext.role = scontext->role; + else + newcontext.role = OBJECT_R_VAL; + } + + /* Set the type to default values. */ + if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { + newcontext.type = scontext->type; + } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { + newcontext.type = tcontext->type; + } else { + if (tclass == policydb->process_class) { + /* Use the type of process. */ + newcontext.type = scontext->type; + } else { + /* Use the type of the related object. */ + newcontext.type = tcontext->type; + } + } + + /* Look for a type transition/member/change rule. */ + avkey.source_type = scontext->type; + avkey.target_type = tcontext->type; + avkey.target_class = tclass; + avkey.specified = specified; + avdatum = ksu_avtab_search(&policydb->te_avtab, &avkey); + + /* If no permanent rule, also check for enabled conditional rules */ + if (!avdatum) { + node = ksu_avtab_search_node(&policydb->te_cond_avtab, &avkey); + for (; node != NULL; + node = ksu_avtab_search_node_next(node, specified)) { + if (node->key.specified & AVTAB_ENABLED) { + avdatum = &node->datum; + break; + } + } + } + + if (avdatum) { + /* Use the type from the type transition/member/change rule. */ + newcontext.type = avdatum->data; + } + + /* Check for class-specific changes. */ + if (specified & AVTAB_TRANSITION) { + /* Look for a role transition rule. */ + for (roletr = policydb->role_tr; roletr; + roletr = roletr->next) { + if (roletr->role == scontext->role && + roletr->type == tcontext->type && + roletr->tclass == tclass) { + /* Use the role transition rule. */ + newcontext.role = roletr->new_role; + break; + } + } + } + + /* Set the MLS attributes. + This is done last because it may allocate memory. */ + rc = ksu_mls_compute_sid(policydb, scontext, tcontext, tclass, specified, + &newcontext); + if (rc) + goto out; + + /* Check the validity of the context. */ + if (!ksu_policydb_context_isvalid(policydb, &newcontext)) { + rc = compute_sid_handle_invalid_context(scontext, + tcontext, + tclass, &newcontext); + if (rc) + goto out; + } + /* Obtain the sid for the context. */ + rc = sepol_sidtab_context_to_sid(sidtab, &newcontext, out_sid); + out: + context_destroy(&newcontext); + return rc; +} + +/* + * Compute a SID to use for labeling a new object in the + * class `tclass' based on a SID pair. + */ +int sepol_transition_sid(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_security_id_t * out_sid) +{ + return sepol_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid); +} + +/* + * Compute a SID to use when selecting a member of a + * polyinstantiated object of class `tclass' based on + * a SID pair. + */ +int sepol_member_sid(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_security_id_t * out_sid) +{ + return sepol_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid); +} + +/* + * Compute a SID to use for relabeling an object in the + * class `tclass' based on a SID pair. + */ +int sepol_change_sid(sepol_security_id_t ssid, + sepol_security_id_t tsid, + sepol_security_class_t tclass, + sepol_security_id_t * out_sid) +{ + return sepol_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid); +} + +/* + * Verify that each permission that is defined under the + * existing policy is still defined with the same value + * in the new policy. + */ +static int validate_perm(hashtab_key_t key, hashtab_datum_t datum, void *p) +{ + hashtab_t h; + perm_datum_t *perdatum, *perdatum2; + + h = (hashtab_t) p; + perdatum = (perm_datum_t *) datum; + + perdatum2 = (perm_datum_t *) hashtab_search(h, key); + if (!perdatum2) { + ERR(NULL, "permission %s disappeared", key); + return -1; + } + if (perdatum->s.value != perdatum2->s.value) { + ERR(NULL, "the value of permissions %s changed", key); + return -1; + } + return 0; +} + +/* + * Verify that each class that is defined under the + * existing policy is still defined with the same + * attributes in the new policy. + */ +static int validate_class(hashtab_key_t key, hashtab_datum_t datum, void *p) +{ + policydb_t *newp; + class_datum_t *cladatum, *cladatum2; + + newp = (policydb_t *) p; + cladatum = (class_datum_t *) datum; + + cladatum2 = + (class_datum_t *) hashtab_search(newp->p_classes.table, key); + if (!cladatum2) { + ERR(NULL, "class %s disappeared", key); + return -1; + } + if (cladatum->s.value != cladatum2->s.value) { + ERR(NULL, "the value of class %s changed", key); + return -1; + } + if ((cladatum->comdatum && !cladatum2->comdatum) || + (!cladatum->comdatum && cladatum2->comdatum)) { + ERR(NULL, "the inherits clause for the access " + "vector definition for class %s changed", key); + return -1; + } + if (cladatum->comdatum) { + if (ksu_hashtab_map + (cladatum->comdatum->permissions.table, validate_perm, + cladatum2->comdatum->permissions.table)) { + ERR(NULL, + " in the access vector definition " + "for class %s", key); + return -1; + } + } + if (ksu_hashtab_map(cladatum->permissions.table, validate_perm, + cladatum2->permissions.table)) { + ERR(NULL, " in access vector definition for class %s", key); + return -1; + } + return 0; +} + +/* Clone the SID into the new SID table. */ +static int clone_sid(sepol_security_id_t sid, + context_struct_t * context, void *arg) +{ + sidtab_t *s = arg; + + return sepol_sidtab_insert(s, sid, context); +} + +static inline int convert_context_handle_invalid_context(context_struct_t * + context) +{ + if (selinux_enforcing) { + return -EINVAL; + } else { + sepol_security_context_t s; + size_t len; + + context_to_string(NULL, policydb, context, &s, &len); + ERR(NULL, "context %s is invalid", s); + free(s); + return 0; + } +} + +typedef struct { + policydb_t *oldp; + policydb_t *newp; +} convert_context_args_t; + +/* + * Convert the values in the security context + * structure `c' from the values specified + * in the policy `p->oldp' to the values specified + * in the policy `p->newp'. Verify that the + * context is valid under the new policy. + */ +static int convert_context(sepol_security_id_t key __attribute__ ((unused)), + context_struct_t * c, void *p) +{ + convert_context_args_t *args; + context_struct_t oldc; + role_datum_t *role; + type_datum_t *typdatum; + user_datum_t *usrdatum; + sepol_security_context_t s; + size_t len; + int rc = -EINVAL; + + args = (convert_context_args_t *) p; + + if (context_cpy(&oldc, c)) + return -ENOMEM; + + /* Convert the user. */ + usrdatum = (user_datum_t *) hashtab_search(args->newp->p_users.table, + args->oldp-> + p_user_val_to_name[c->user - + 1]); + + if (!usrdatum) { + goto bad; + } + c->user = usrdatum->s.value; + + /* Convert the role. */ + role = (role_datum_t *) hashtab_search(args->newp->p_roles.table, + args->oldp-> + p_role_val_to_name[c->role - 1]); + if (!role) { + goto bad; + } + c->role = role->s.value; + + /* Convert the type. */ + typdatum = (type_datum_t *) + hashtab_search(args->newp->p_types.table, + args->oldp->p_type_val_to_name[c->type - 1]); + if (!typdatum) { + goto bad; + } + c->type = typdatum->s.value; + + rc = ksu_mls_convert_context(args->oldp, args->newp, c); + if (rc) + goto bad; + + /* Check the validity of the new context. */ + if (!ksu_policydb_context_isvalid(args->newp, c)) { + rc = convert_context_handle_invalid_context(&oldc); + if (rc) + goto bad; + } + + context_destroy(&oldc); + return 0; + + bad: + context_to_string(NULL, policydb, &oldc, &s, &len); + context_destroy(&oldc); + ERR(NULL, "invalidating context %s", s); + free(s); + return rc; +} + +/* Reading from a policy "file". */ +int next_entry(void *buf, struct policy_file *fp, size_t bytes) +{ + // size_t nread; + + switch (fp->type) { + case PF_USE_STDIO: +#if 0 + nread = fread(buf, bytes, 1, fp->fp); + + if (nread != 1) + return -1; + break; +#else + // don't support read from 'stdio' + return -1; +#endif + case PF_USE_MEMORY: + if (bytes > fp->len) { + // errno = EOVERFLOW; + return -1; + } + memcpy(buf, fp->data, bytes); + fp->data += bytes; + fp->len -= bytes; + break; + default: + // errno = EINVAL; + return -1; + } + return 0; +} + +size_t put_entry(const void *ptr, size_t size, size_t n, + struct policy_file *fp) +{ + size_t bytes = size * n; + + switch (fp->type) { + case PF_USE_STDIO: + // return fwrite(ptr, size, n, fp->fp); + return -1; + case PF_USE_MEMORY: + if (bytes > fp->len) { + // errno = ENOSPC; + return 0; + } + + memcpy(fp->data, ptr, bytes); + fp->data += bytes; + fp->len -= bytes; + return n; + case PF_LEN: + fp->len += bytes; + return n; + default: + return 0; + } + return 0; +} + +/* + * Reads a string and null terminates it from the policy file. + * This is a port of str_read from the SE Linux kernel code. + * + * It returns: + * 0 - Success + * -1 - Failure with errno set + */ +int str_read(char **strp, struct policy_file *fp, size_t len) +{ + int rc; + char *str; + + if (zero_or_saturated(len)) { + // errno = EINVAL; + return -1; + } + + str = malloc(len + 1); + if (!str) + return -1; + + /* it's expected the caller should free the str */ + *strp = str; + + /* next_entry sets errno */ + rc = next_entry(str, fp, len); + if (rc) + return rc; + + str[len] = '\0'; + return 0; +} + +/* + * Read a new set of configuration data from + * a policy database binary representation file. + * + * Verify that each class that is defined under the + * existing policy is still defined with the same + * attributes in the new policy. + * + * Convert the context structures in the SID table to the + * new representation and verify that all entries + * in the SID table are valid under the new policy. + * + * Change the active policy database to use the new + * configuration data. + * + * Reset the access vector cache. + */ +int sepol_load_policy(void *data, size_t len) +{ + policydb_t oldpolicydb, newpolicydb; + sidtab_t oldsidtab, newsidtab; + convert_context_args_t args; + int rc = 0; + struct policy_file file, *fp; + + policy_file_init(&file); + file.type = PF_USE_MEMORY; + file.data = data; + file.len = len; + fp = &file; + + if (policydb_init(&newpolicydb)) + return -ENOMEM; + + if (ksu_policydb_read(&newpolicydb, fp, 1)) { + ksu_policydb_destroy(&mypolicydb); + return -EINVAL; + } + + sepol_sidtab_init(&newsidtab); + + /* Verify that the existing classes did not change. */ + if (ksu_hashtab_map + (policydb->p_classes.table, validate_class, &newpolicydb)) { + ERR(NULL, "the definition of an existing class changed"); + rc = -EINVAL; + goto err; + } + + /* Clone the SID table. */ + sepol_sidtab_shutdown(sidtab); + if (sepol_sidtab_map(sidtab, clone_sid, &newsidtab)) { + rc = -ENOMEM; + goto err; + } + + /* Convert the internal representations of contexts + in the new SID table and remove invalid SIDs. */ + args.oldp = policydb; + args.newp = &newpolicydb; + sepol_sidtab_map_remove_on_error(&newsidtab, convert_context, &args); + + /* Save the old policydb and SID table to free later. */ + memcpy(&oldpolicydb, policydb, sizeof *policydb); + sepol_sidtab_set(&oldsidtab, sidtab); + + /* Install the new policydb and SID table. */ + memcpy(policydb, &newpolicydb, sizeof *policydb); + sepol_sidtab_set(sidtab, &newsidtab); + + /* Free the old policydb and SID table. */ + ksu_policydb_destroy(&oldpolicydb); + sepol_sidtab_destroy(&oldsidtab); + + return 0; + + err: + sepol_sidtab_destroy(&newsidtab); + ksu_policydb_destroy(&newpolicydb); + return rc; + +} + +/* + * Return the SIDs to use for an unlabeled file system + * that is being mounted from the device with the + * the kdevname `name'. The `fs_sid' SID is returned for + * the file system and the `file_sid' SID is returned + * for all files within that file system. + */ +int sepol_fs_sid(char *name, + sepol_security_id_t * fs_sid, + sepol_security_id_t * file_sid) +{ + int rc = 0; + ocontext_t *c; + + c = policydb->ocontexts[OCON_FS]; + while (c) { + if (strcmp(c->u.name, name) == 0) + break; + c = c->next; + } + + if (c) { + if (!c->sid[0] || !c->sid[1]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[1], + &c->sid[1]); + if (rc) + goto out; + } + *fs_sid = c->sid[0]; + *file_sid = c->sid[1]; + } else { + *fs_sid = SECINITSID_FS; + *file_sid = SECINITSID_FILE; + } + + out: + return rc; +} + +/* + * Return the SID of the ibpkey specified by + * `subnet prefix', and `pkey number'. + */ +int sepol_ibpkey_sid(uint64_t subnet_prefix, + uint16_t pkey, sepol_security_id_t *out_sid) +{ + ocontext_t *c; + int rc = 0; + + c = policydb->ocontexts[OCON_IBPKEY]; + while (c) { + if (c->u.ibpkey.low_pkey <= pkey && + c->u.ibpkey.high_pkey >= pkey && + subnet_prefix == c->u.ibpkey.subnet_prefix) + break; + c = c->next; + } + + if (c) { + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *out_sid = c->sid[0]; + } else { + *out_sid = SECINITSID_UNLABELED; + } + +out: + return rc; +} + +/* + * Return the SID of the subnet management interface specified by + * `device name', and `port'. + */ +int sepol_ibendport_sid(char *dev_name, + uint8_t port, + sepol_security_id_t *out_sid) +{ + ocontext_t *c; + int rc = 0; + + c = policydb->ocontexts[OCON_IBENDPORT]; + while (c) { + if (c->u.ibendport.port == port && + !strcmp(dev_name, c->u.ibendport.dev_name)) + break; + c = c->next; + } + + if (c) { + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *out_sid = c->sid[0]; + } else { + *out_sid = SECINITSID_UNLABELED; + } + +out: + return rc; +} + + +/* + * Return the SID of the port specified by + * `domain', `type', `protocol', and `port'. + */ +int sepol_port_sid(uint16_t domain __attribute__ ((unused)), + uint16_t type __attribute__ ((unused)), + uint8_t protocol, + uint16_t port, sepol_security_id_t * out_sid) +{ + ocontext_t *c; + int rc = 0; + + c = policydb->ocontexts[OCON_PORT]; + while (c) { + if (c->u.port.protocol == protocol && + c->u.port.low_port <= port && c->u.port.high_port >= port) + break; + c = c->next; + } + + if (c) { + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *out_sid = c->sid[0]; + } else { + *out_sid = SECINITSID_PORT; + } + + out: + return rc; +} + +/* + * Return the SIDs to use for a network interface + * with the name `name'. The `if_sid' SID is returned for + * the interface and the `msg_sid' SID is returned as + * the default SID for messages received on the + * interface. + */ +int sepol_netif_sid(char *name, + sepol_security_id_t * if_sid, + sepol_security_id_t * msg_sid) +{ + int rc = 0; + ocontext_t *c; + + c = policydb->ocontexts[OCON_NETIF]; + while (c) { + if (strcmp(name, c->u.name) == 0) + break; + c = c->next; + } + + if (c) { + if (!c->sid[0] || !c->sid[1]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[1], + &c->sid[1]); + if (rc) + goto out; + } + *if_sid = c->sid[0]; + *msg_sid = c->sid[1]; + } else { + *if_sid = SECINITSID_NETIF; + *msg_sid = SECINITSID_NETMSG; + } + + out: + return rc; +} + +static int match_ipv6_addrmask(uint32_t * input, uint32_t * addr, + uint32_t * mask) +{ + int i, fail = 0; + + for (i = 0; i < 4; i++) + if (addr[i] != (input[i] & mask[i])) { + fail = 1; + break; + } + + return !fail; +} + +/* + * Return the SID of the node specified by the address + * `addrp' where `addrlen' is the length of the address + * in bytes and `domain' is the communications domain or + * address family in which the address should be interpreted. + */ +int sepol_node_sid(uint16_t domain, + void *addrp, + size_t addrlen, sepol_security_id_t * out_sid) +{ + int rc = 0; + ocontext_t *c; + + switch (domain) { + case AF_INET:{ + uint32_t addr; + + if (addrlen != sizeof(uint32_t)) { + rc = -EINVAL; + goto out; + } + + addr = *((uint32_t *) addrp); + + c = policydb->ocontexts[OCON_NODE]; + while (c) { + if (c->u.node.addr == (addr & c->u.node.mask)) + break; + c = c->next; + } + break; + } + + case AF_INET6: + if (addrlen != sizeof(uint64_t) * 2) { + rc = -EINVAL; + goto out; + } + + c = policydb->ocontexts[OCON_NODE6]; + while (c) { + if (match_ipv6_addrmask(addrp, c->u.node6.addr, + c->u.node6.mask)) + break; + c = c->next; + } + break; + + default: + *out_sid = SECINITSID_NODE; + goto out; + } + + if (c) { + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *out_sid = c->sid[0]; + } else { + *out_sid = SECINITSID_NODE; + } + + out: + return rc; +} + +/* + * Generate the set of SIDs for legal security contexts + * for a given user that can be reached by `fromsid'. + * Set `*sids' to point to a dynamically allocated + * array containing the set of SIDs. Set `*nel' to the + * number of elements in the array. + */ +#define SIDS_NEL 25 + +int sepol_get_user_sids(sepol_security_id_t fromsid, + char *username, + sepol_security_id_t ** sids, uint32_t * nel) +{ + context_struct_t *fromcon, usercon; + sepol_security_id_t *mysids, *mysids2, sid; + uint32_t mynel = 0, maxnel = SIDS_NEL; + user_datum_t *user; + role_datum_t *role; + struct sepol_av_decision avd; + int rc = 0; + unsigned int i, j, reason; + ebitmap_node_t *rnode, *tnode; + + fromcon = sepol_sidtab_search(sidtab, fromsid); + if (!fromcon) { + rc = -EINVAL; + goto out; + } + + user = (user_datum_t *) hashtab_search(policydb->p_users.table, + username); + if (!user) { + rc = -EINVAL; + goto out; + } + usercon.user = user->s.value; + + mysids = calloc(maxnel, sizeof(sepol_security_id_t)); + if (!mysids) { + rc = -ENOMEM; + goto out; + } + + ebitmap_for_each_positive_bit(&user->roles.roles, rnode, i) { + role = policydb->role_val_to_struct[i]; + usercon.role = i + 1; + ebitmap_for_each_positive_bit(&role->types.types, tnode, j) { + usercon.type = j + 1; + if (usercon.type == fromcon->type) + continue; + + if (ksu_mls_setup_user_range + (fromcon, user, &usercon, policydb->mls)) + continue; + + rc = context_struct_compute_av(fromcon, &usercon, + policydb->process_class, + policydb->process_trans, + &avd, &reason, NULL, 0); + if (rc || !(avd.allowed & policydb->process_trans)) + continue; + rc = sepol_sidtab_context_to_sid(sidtab, &usercon, + &sid); + if (rc) { + free(mysids); + goto out; + } + if (mynel < maxnel) { + mysids[mynel++] = sid; + } else { + maxnel += SIDS_NEL; + mysids2 = calloc(maxnel, sizeof(sepol_security_id_t)); + if (!mysids2) { + rc = -ENOMEM; + free(mysids); + goto out; + } + memcpy(mysids2, mysids, + mynel * sizeof(sepol_security_id_t)); + free(mysids); + mysids = mysids2; + mysids[mynel++] = sid; + } + } + } + + *sids = mysids; + *nel = mynel; + + out: + return rc; +} + +/* + * Return the SID to use for a file in a filesystem + * that cannot support a persistent label mapping or use another + * fixed labeling behavior like transition SIDs or task SIDs. + */ +int sepol_genfs_sid(const char *fstype, + const char *path, + sepol_security_class_t sclass, + sepol_security_id_t * sid) +{ + size_t len; + genfs_t *genfs; + ocontext_t *c; + int rc = 0, cmp = 0; + + for (genfs = policydb->genfs; genfs; genfs = genfs->next) { + cmp = strcmp(fstype, genfs->fstype); + if (cmp <= 0) + break; + } + + if (!genfs || cmp) { + *sid = SECINITSID_UNLABELED; + rc = -ENOENT; + goto out; + } + + for (c = genfs->head; c; c = c->next) { + len = strlen(c->u.name); + if ((!c->v.sclass || sclass == c->v.sclass) && + (strncmp(c->u.name, path, len) == 0)) + break; + } + + if (!c) { + *sid = SECINITSID_UNLABELED; + rc = -ENOENT; + goto out; + } + + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], &c->sid[0]); + if (rc) + goto out; + } + + *sid = c->sid[0]; + out: + return rc; +} + +int sepol_fs_use(const char *fstype, + unsigned int *behavior, sepol_security_id_t * sid) +{ + int rc = 0; + ocontext_t *c; + + c = policydb->ocontexts[OCON_FSUSE]; + while (c) { + if (strcmp(fstype, c->u.name) == 0) + break; + c = c->next; + } + + if (c) { + *behavior = c->v.behavior; + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *sid = c->sid[0]; + } else { + rc = sepol_genfs_sid(fstype, "/", policydb->dir_class, sid); + if (rc) { + *behavior = SECURITY_FS_USE_NONE; + rc = 0; + } else { + *behavior = SECURITY_FS_USE_GENFS; + } + } + + out: + return rc; +} + +/* FLASK */ diff --git a/kernel/libsepol/src/services.o b/kernel/libsepol/src/services.o new file mode 100644 index 00000000..bc1a8fca Binary files /dev/null and b/kernel/libsepol/src/services.o differ diff --git a/kernel/libsepol/src/sidtab.c b/kernel/libsepol/src/sidtab.c new file mode 100644 index 00000000..9845e127 --- /dev/null +++ b/kernel/libsepol/src/sidtab.c @@ -0,0 +1,294 @@ + +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * Implementation of the SID table type. + */ + +// #include +// #include +#include +// #include + +#include + +#include "flask.h" +#include "private.h" + +#define SIDTAB_HASH(sid) \ +(sid & SIDTAB_HASH_MASK) + +#define INIT_SIDTAB_LOCK(s) +#define SIDTAB_LOCK(s) +#define SIDTAB_UNLOCK(s) + +int sepol_sidtab_init(sidtab_t * s) +{ + s->htable = calloc(SIDTAB_SIZE, sizeof(sidtab_ptr_t)); + if (!s->htable) + return -ENOMEM; + s->nel = 0; + s->next_sid = 1; + s->shutdown = 0; + INIT_SIDTAB_LOCK(s); + return 0; +} + +int sepol_sidtab_insert(sidtab_t * s, sepol_security_id_t sid, + context_struct_t * context) +{ + int hvalue; + sidtab_node_t *prev, *cur, *newnode; + + if (!s || !s->htable) + return -ENOMEM; + + hvalue = SIDTAB_HASH(sid); + prev = NULL; + cur = s->htable[hvalue]; + while (cur != NULL && sid > cur->sid) { + prev = cur; + cur = cur->next; + } + + if (cur && sid == cur->sid) { + // errno = EEXIST; + return -EEXIST; + } + + newnode = (sidtab_node_t *) malloc(sizeof(sidtab_node_t)); + if (newnode == NULL) + return -ENOMEM; + newnode->sid = sid; + if (context_cpy(&newnode->context, context)) { + free(newnode); + return -ENOMEM; + } + + if (prev) { + newnode->next = prev->next; + prev->next = newnode; + } else { + newnode->next = s->htable[hvalue]; + s->htable[hvalue] = newnode; + } + + s->nel++; + if (sid >= s->next_sid) + s->next_sid = sid + 1; + return 0; +} + +context_struct_t *sepol_sidtab_search(sidtab_t * s, sepol_security_id_t sid) +{ + int hvalue; + sidtab_node_t *cur; + + if (!s || !s->htable) + return NULL; + + hvalue = SIDTAB_HASH(sid); + cur = s->htable[hvalue]; + while (cur != NULL && sid > cur->sid) + cur = cur->next; + + if (cur == NULL || sid != cur->sid) { + /* Remap invalid SIDs to the unlabeled SID. */ + sid = SECINITSID_UNLABELED; + hvalue = SIDTAB_HASH(sid); + cur = s->htable[hvalue]; + while (cur != NULL && sid > cur->sid) + cur = cur->next; + if (!cur || sid != cur->sid) + return NULL; + } + + return &cur->context; +} + +int sepol_sidtab_map(sidtab_t * s, + int (*apply) (sepol_security_id_t sid, + context_struct_t * context, + void *args), void *args) +{ + int i, ret; + sidtab_node_t *cur; + + if (!s || !s->htable) + return 0; + + for (i = 0; i < SIDTAB_SIZE; i++) { + cur = s->htable[i]; + while (cur != NULL) { + ret = apply(cur->sid, &cur->context, args); + if (ret) + return ret; + cur = cur->next; + } + } + return 0; +} + +void sepol_sidtab_map_remove_on_error(sidtab_t * s, + int (*apply) (sepol_security_id_t sid, + context_struct_t * context, + void *args), void *args) +{ + int i, ret; + sidtab_node_t *last, *cur, *temp; + + if (!s || !s->htable) + return; + + for (i = 0; i < SIDTAB_SIZE; i++) { + last = NULL; + cur = s->htable[i]; + while (cur != NULL) { + ret = apply(cur->sid, &cur->context, args); + if (ret) { + if (last) { + last->next = cur->next; + } else { + s->htable[i] = cur->next; + } + + temp = cur; + cur = cur->next; + context_destroy(&temp->context); + free(temp); + s->nel--; + } else { + last = cur; + cur = cur->next; + } + } + } + + return; +} + +static inline sepol_security_id_t sepol_sidtab_search_context(sidtab_t * s, + context_struct_t * + context) +{ + int i; + sidtab_node_t *cur; + + for (i = 0; i < SIDTAB_SIZE; i++) { + cur = s->htable[i]; + while (cur != NULL) { + if (context_cmp(&cur->context, context)) + return cur->sid; + cur = cur->next; + } + } + return 0; +} + +int sepol_sidtab_context_to_sid(sidtab_t * s, + context_struct_t * context, + sepol_security_id_t * out_sid) +{ + sepol_security_id_t sid; + int ret = 0; + + *out_sid = SEPOL_SECSID_NULL; + + sid = sepol_sidtab_search_context(s, context); + if (!sid) { + SIDTAB_LOCK(s); + /* Rescan now that we hold the lock. */ + sid = sepol_sidtab_search_context(s, context); + if (sid) + goto unlock_out; + /* No SID exists for the context. Allocate a new one. */ + if (s->next_sid == UINT_MAX || s->shutdown) { + ret = -ENOMEM; + goto unlock_out; + } + sid = s->next_sid++; + ret = sepol_sidtab_insert(s, sid, context); + if (ret) + s->next_sid--; + unlock_out: + SIDTAB_UNLOCK(s); + } + + if (ret) + return ret; + + *out_sid = sid; + return 0; +} + +void sepol_sidtab_hash_eval(sidtab_t * h, char *tag) +{ + int i, chain_len, slots_used, max_chain_len; + sidtab_node_t *cur; + + slots_used = 0; + max_chain_len = 0; + for (i = 0; i < SIDTAB_SIZE; i++) { + cur = h->htable[i]; + if (cur) { + slots_used++; + chain_len = 0; + while (cur) { + chain_len++; + cur = cur->next; + } + + if (chain_len > max_chain_len) + max_chain_len = chain_len; + } + } + + printf + ("%s: %d entries and %d/%d buckets used, longest chain length %d\n", + tag, h->nel, slots_used, SIDTAB_SIZE, max_chain_len); +} + +void sepol_sidtab_destroy(sidtab_t * s) +{ + int i; + sidtab_ptr_t cur, temp; + + if (!s || !s->htable) + return; + + for (i = 0; i < SIDTAB_SIZE; i++) { + cur = s->htable[i]; + while (cur != NULL) { + temp = cur; + cur = cur->next; + context_destroy(&temp->context); + free(temp); + } + s->htable[i] = NULL; + } + free(s->htable); + s->htable = NULL; + s->nel = 0; + s->next_sid = 1; +} + +void sepol_sidtab_set(sidtab_t * dst, sidtab_t * src) +{ + SIDTAB_LOCK(src); + dst->htable = src->htable; + dst->nel = src->nel; + dst->next_sid = src->next_sid; + dst->shutdown = 0; + SIDTAB_UNLOCK(src); +} + +void sepol_sidtab_shutdown(sidtab_t * s) +{ + SIDTAB_LOCK(s); + s->shutdown = 1; + SIDTAB_UNLOCK(s); +} + +/* FLASK */ diff --git a/kernel/libsepol/src/sidtab.o b/kernel/libsepol/src/sidtab.o new file mode 100644 index 00000000..3ac0e205 Binary files /dev/null and b/kernel/libsepol/src/sidtab.o differ diff --git a/kernel/libsepol/src/symtab.c b/kernel/libsepol/src/symtab.c new file mode 100644 index 00000000..dbde36ed --- /dev/null +++ b/kernel/libsepol/src/symtab.c @@ -0,0 +1,57 @@ + +/* Author : Stephen Smalley, */ + +/* FLASK */ + +/* + * Implementation of the symbol table type. + */ + +#include + +#include "private.h" + +#include +#include + +ignore_unsigned_overflow_ +static unsigned int symhash(hashtab_t h, const_hashtab_key_t key) +{ + const char *p, *keyp; + size_t size; + unsigned int val; + + val = 0; + keyp = (const char *)key; + size = strlen(keyp); + for (p = keyp; ((size_t) (p - keyp)) < size; p++) + val = + (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); + return val & (h->size - 1); +} + +static int symcmp(hashtab_t h + __attribute__ ((unused)), const_hashtab_key_t key1, + const_hashtab_key_t key2) +{ + return strcmp(key1, key2); +} + +int ksu_symtab_init(symtab_t * s, unsigned int size) +{ + s->table = hashtab_create(symhash, symcmp, size); + if (!s->table) + return -1; + s->nprim = 0; + return 0; +} + +void symtab_destroy(symtab_t * s) +{ + if (!s) + return; + if (s->table) + ksu_hashtab_destroy(s->table); + return; +} +/* FLASK */ diff --git a/kernel/libsepol/src/symtab.o b/kernel/libsepol/src/symtab.o new file mode 100644 index 00000000..aa6ad7a5 Binary files /dev/null and b/kernel/libsepol/src/symtab.o differ diff --git a/kernel/libsepol/src/user_internal.h b/kernel/libsepol/src/user_internal.h new file mode 100644 index 00000000..f5b22b02 --- /dev/null +++ b/kernel/libsepol/src/user_internal.h @@ -0,0 +1,7 @@ +#ifndef _SEPOL_USER_INTERNAL_H_ +#define _SEPOL_USER_INTERNAL_H_ + +#include +#include + +#endif diff --git a/kernel/libsepol/src/user_record.c b/kernel/libsepol/src/user_record.c new file mode 100644 index 00000000..63536d26 --- /dev/null +++ b/kernel/libsepol/src/user_record.c @@ -0,0 +1,379 @@ +// #include +// #include +#include + +#include "user_internal.h" +#include "debug.h" +#include "private.h" + +struct sepol_user { + /* This user's name */ + char *name; + + /* This user's mls level (only required for mls) */ + char *mls_level; + + /* This user's mls range (only required for mls) */ + char *mls_range; + + /* The role array */ + char **roles; + + /* The number of roles */ + unsigned int num_roles; +}; + +struct sepol_user_key { + /* This user's name */ + char *name; +}; + +int sepol_user_key_create(sepol_handle_t * handle, + const char *name, sepol_user_key_t ** key_ptr) +{ + + sepol_user_key_t *tmp_key = + (sepol_user_key_t *) malloc(sizeof(sepol_user_key_t)); + + if (!tmp_key) { + ERR(handle, "out of memory, " + "could not create selinux user key"); + return STATUS_ERR; + } + + tmp_key->name = strdup(name); + if (!tmp_key->name) { + ERR(handle, "out of memory, could not create selinux user key"); + free(tmp_key); + return STATUS_ERR; + } + + *key_ptr = tmp_key; + return STATUS_SUCCESS; +} + + +void sepol_user_key_unpack(const sepol_user_key_t * key, const char **name) +{ + + *name = key->name; +} + + +int sepol_user_key_extract(sepol_handle_t * handle, + const sepol_user_t * user, + sepol_user_key_t ** key_ptr) +{ + + if (sepol_user_key_create(handle, user->name, key_ptr) < 0) { + ERR(handle, "could not extract key from user %s", user->name); + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_user_key_free(sepol_user_key_t * key) +{ + if (!key) + return; + free(key->name); + free(key); +} + +int sepol_user_compare(const sepol_user_t * user, const sepol_user_key_t * key) +{ + + return strcmp(user->name, key->name); +} + +int sepol_user_compare2(const sepol_user_t * user, const sepol_user_t * user2) +{ + + return strcmp(user->name, user2->name); +} + +/* Name */ +const char *sepol_user_get_name(const sepol_user_t * user) +{ + + return user->name; +} + +int sepol_user_set_name(sepol_handle_t * handle, + sepol_user_t * user, const char *name) +{ + + char *tmp_name = strdup(name); + if (!tmp_name) { + ERR(handle, "out of memory, could not set name"); + return STATUS_ERR; + } + free(user->name); + user->name = tmp_name; + return STATUS_SUCCESS; +} + + +/* MLS */ +const char *sepol_user_get_mlslevel(const sepol_user_t * user) +{ + + return user->mls_level; +} + + +int sepol_user_set_mlslevel(sepol_handle_t * handle, + sepol_user_t * user, const char *mls_level) +{ + + char *tmp_mls_level = strdup(mls_level); + if (!tmp_mls_level) { + ERR(handle, "out of memory, " + "could not set MLS default level"); + return STATUS_ERR; + } + free(user->mls_level); + user->mls_level = tmp_mls_level; + return STATUS_SUCCESS; +} + + +const char *sepol_user_get_mlsrange(const sepol_user_t * user) +{ + + return user->mls_range; +} + + +int sepol_user_set_mlsrange(sepol_handle_t * handle, + sepol_user_t * user, const char *mls_range) +{ + + char *tmp_mls_range = strdup(mls_range); + if (!tmp_mls_range) { + ERR(handle, "out of memory, " + "could not set MLS allowed range"); + return STATUS_ERR; + } + free(user->mls_range); + user->mls_range = tmp_mls_range; + return STATUS_SUCCESS; +} + + +/* Roles */ +int sepol_user_get_num_roles(const sepol_user_t * user) +{ + + return user->num_roles; +} + +int sepol_user_add_role(sepol_handle_t * handle, + sepol_user_t * user, const char *role) +{ + + char *role_cp; + char **roles_realloc = NULL; + + if (sepol_user_has_role(user, role)) + return STATUS_SUCCESS; + + role_cp = strdup(role); + if (!role_cp) + goto omem; + + roles_realloc = reallocarray(user->roles, + user->num_roles + 1, + sizeof(char *)); + if (!roles_realloc) + goto omem; + + user->num_roles++; + user->roles = roles_realloc; + user->roles[user->num_roles - 1] = role_cp; + + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory, could not add role %s", role); + free(role_cp); + free(roles_realloc); + return STATUS_ERR; +} + + +int sepol_user_has_role(const sepol_user_t * user, const char *role) +{ + + unsigned int i; + + for (i = 0; i < user->num_roles; i++) + if (!strcmp(user->roles[i], role)) + return 1; + return 0; +} + + +int sepol_user_set_roles(sepol_handle_t * handle, + sepol_user_t * user, + const char **roles_arr, unsigned int num_roles) +{ + + unsigned int i; + char **tmp_roles = NULL; + + if (num_roles > 0) { + + /* First, make a copy */ + tmp_roles = (char **)calloc(1, sizeof(char *) * num_roles); + if (!tmp_roles) + goto omem; + + for (i = 0; i < num_roles; i++) { + tmp_roles[i] = strdup(roles_arr[i]); + if (!tmp_roles[i]) + goto omem; + } + } + + /* Apply other changes */ + for (i = 0; i < user->num_roles; i++) + free(user->roles[i]); + free(user->roles); + user->roles = tmp_roles; + user->num_roles = num_roles; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory, could not allocate roles array for" + "user %s", user->name); + + if (tmp_roles) { + for (i = 0; i < num_roles; i++) { + if (!tmp_roles[i]) + break; + free(tmp_roles[i]); + } + } + free(tmp_roles); + return STATUS_ERR; +} + +int sepol_user_get_roles(sepol_handle_t * handle, + const sepol_user_t * user, + const char ***roles_arr, unsigned int *num_roles) +{ + + unsigned int i; + const char **tmp_roles = + (const char **)calloc(user->num_roles, sizeof(char *)); + if (!tmp_roles) + goto omem; + + for (i = 0; i < user->num_roles; i++) + tmp_roles[i] = user->roles[i]; + + *roles_arr = tmp_roles; + *num_roles = user->num_roles; + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory, could not " + "allocate roles array for user %s", user->name); + free(tmp_roles); + return STATUS_ERR; +} + + +void sepol_user_del_role(sepol_user_t * user, const char *role) +{ + + unsigned int i; + for (i = 0; i < user->num_roles; i++) { + if (!strcmp(user->roles[i], role)) { + free(user->roles[i]); + user->roles[i] = NULL; + user->roles[i] = user->roles[user->num_roles - 1]; + user->num_roles--; + } + } +} + +/* Create */ +int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr) +{ + + sepol_user_t *user = (sepol_user_t *) malloc(sizeof(sepol_user_t)); + + if (!user) { + ERR(handle, "out of memory, " + "could not create selinux user record"); + return STATUS_ERR; + } + + user->roles = NULL; + user->num_roles = 0; + user->name = NULL; + user->mls_level = NULL; + user->mls_range = NULL; + + *user_ptr = user; + return STATUS_SUCCESS; +} + + +/* Deep copy clone */ +int sepol_user_clone(sepol_handle_t * handle, + const sepol_user_t * user, sepol_user_t ** user_ptr) +{ + + sepol_user_t *new_user = NULL; + unsigned int i; + + if (sepol_user_create(handle, &new_user) < 0) + goto err; + + if (sepol_user_set_name(handle, new_user, user->name) < 0) + goto err; + + for (i = 0; i < user->num_roles; i++) { + if (sepol_user_add_role(handle, new_user, user->roles[i]) < 0) + goto err; + } + + if (user->mls_level && + (sepol_user_set_mlslevel(handle, new_user, user->mls_level) < 0)) + goto err; + + if (user->mls_range && + (sepol_user_set_mlsrange(handle, new_user, user->mls_range) < 0)) + goto err; + + *user_ptr = new_user; + return STATUS_SUCCESS; + + err: + ERR(handle, "could not clone selinux user record"); + sepol_user_free(new_user); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_user_free(sepol_user_t * user) +{ + + unsigned int i; + + if (!user) + return; + + free(user->name); + for (i = 0; i < user->num_roles; i++) + free(user->roles[i]); + free(user->roles); + free(user->mls_level); + free(user->mls_range); + free(user); +} + diff --git a/kernel/libsepol/src/user_record.o b/kernel/libsepol/src/user_record.o new file mode 100644 index 00000000..1c233840 Binary files /dev/null and b/kernel/libsepol/src/user_record.o differ diff --git a/kernel/libsepol/src/users.c b/kernel/libsepol/src/users.c new file mode 100644 index 00000000..a12f5be1 --- /dev/null +++ b/kernel/libsepol/src/users.c @@ -0,0 +1,379 @@ +// #include +// #include +#include + +#include "private.h" +#include "debug.h" +#include "handle.h" + +#include +#include +#include +#include "user_internal.h" +#include "mls.h" + +static int user_to_record(sepol_handle_t * handle, + const policydb_t * policydb, + int user_idx, sepol_user_t ** record) +{ + + const char *name = policydb->p_user_val_to_name[user_idx]; + user_datum_t *usrdatum = policydb->user_val_to_struct[user_idx]; + ebitmap_t *roles; + ebitmap_node_t *rnode; + unsigned bit; + + sepol_user_t *tmp_record = NULL; + + if (!usrdatum) + goto err; + + roles = &(usrdatum->roles.roles); + + if (sepol_user_create(handle, &tmp_record) < 0) + goto err; + + if (sepol_user_set_name(handle, tmp_record, name) < 0) + goto err; + + /* Extract roles */ + ebitmap_for_each_positive_bit(roles, rnode, bit) { + char *role = policydb->p_role_val_to_name[bit]; + if (sepol_user_add_role(handle, tmp_record, role) < 0) + goto err; + } + + /* Extract MLS info */ + if (policydb->mls) { + context_struct_t context; + char *str; + + context_init(&context); + if (mls_level_cpy(&context.range.level[0], + &usrdatum->exp_dfltlevel) < 0) { + ERR(handle, "could not copy MLS level"); + context_destroy(&context); + goto err; + } + if (mls_level_cpy(&context.range.level[1], + &usrdatum->exp_dfltlevel) < 0) { + ERR(handle, "could not copy MLS level"); + context_destroy(&context); + goto err; + } + if (mls_to_string(handle, policydb, &context, &str) < 0) { + context_destroy(&context); + goto err; + } + context_destroy(&context); + + if (sepol_user_set_mlslevel(handle, tmp_record, str) < 0) { + free(str); + goto err; + } + free(str); + + context_init(&context); + if (mls_range_cpy(&context.range, &usrdatum->exp_range) < 0) { + ERR(handle, "could not copy MLS range"); + context_destroy(&context); + goto err; + } + if (mls_to_string(handle, policydb, &context, &str) < 0) { + context_destroy(&context); + goto err; + } + context_destroy(&context); + + if (sepol_user_set_mlsrange(handle, tmp_record, str) < 0) { + free(str); + goto err; + } + free(str); + } + + *record = tmp_record; + return STATUS_SUCCESS; + + err: + /* FIXME: handle error */ + sepol_user_free(tmp_record); + return STATUS_ERR; +} + +int sepol_user_modify(sepol_handle_t * handle, + sepol_policydb_t * p, + const sepol_user_key_t * key, const sepol_user_t * user) +{ + + policydb_t *policydb = &p->p; + + /* For user data */ + const char *cname, *cmls_level, *cmls_range; + char *name = NULL; + + const char **roles = NULL; + unsigned int num_roles = 0; + + /* Low-level representation */ + user_datum_t *usrdatum = NULL; + role_datum_t *roldatum; + unsigned int i; + + context_struct_t context; + unsigned bit; + int new = 0; + + ebitmap_node_t *rnode; + + /* First, extract all the data */ + sepol_user_key_unpack(key, &cname); + + cmls_level = sepol_user_get_mlslevel(user); + cmls_range = sepol_user_get_mlsrange(user); + + /* Make sure that worked properly */ + if (sepol_user_get_roles(handle, user, &roles, &num_roles) < 0) + goto err; + + /* Now, see if a user exists */ + usrdatum = hashtab_search(policydb->p_users.table, cname); + + /* If it does, we will modify it */ + if (usrdatum) { + + int value_cp = usrdatum->s.value; + user_datum_destroy(usrdatum); + user_datum_init(usrdatum); + usrdatum->s.value = value_cp; + + /* Otherwise, create a new one */ + } else { + usrdatum = (user_datum_t *) malloc(sizeof(user_datum_t)); + if (!usrdatum) + goto omem; + user_datum_init(usrdatum); + new = 1; + } + + /* For every role */ + for (i = 0; i < num_roles; i++) { + + /* Search for the role */ + roldatum = hashtab_search(policydb->p_roles.table, roles[i]); + if (!roldatum) { + ERR(handle, "undefined role %s for user %s", + roles[i], cname); + goto err; + } + + /* Set the role and every role it dominates */ + ebitmap_for_each_positive_bit(&roldatum->dominates, rnode, bit) { + if (ksu_ebitmap_set_bit(&(usrdatum->roles.roles), bit, 1)) + goto omem; + } + } + + /* For MLS systems */ + if (policydb->mls) { + + /* MLS level */ + if (cmls_level == NULL) { + ERR(handle, "MLS is enabled, but no MLS " + "default level was defined for user %s", cname); + goto err; + } + + context_init(&context); + if (ksu_mls_from_string(handle, policydb, cmls_level, &context) < 0) { + context_destroy(&context); + goto err; + } + if (mls_level_cpy(&usrdatum->exp_dfltlevel, + &context.range.level[0]) < 0) { + ERR(handle, "could not copy MLS level %s", cmls_level); + context_destroy(&context); + goto err; + } + context_destroy(&context); + + /* MLS range */ + if (cmls_range == NULL) { + ERR(handle, "MLS is enabled, but no MLS" + "range was defined for user %s", cname); + goto err; + } + + context_init(&context); + if (ksu_mls_from_string(handle, policydb, cmls_range, &context) < 0) { + context_destroy(&context); + goto err; + } + if (mls_range_cpy(&usrdatum->exp_range, &context.range) < 0) { + ERR(handle, "could not copy MLS range %s", cmls_range); + context_destroy(&context); + goto err; + } + context_destroy(&context); + } else if (cmls_level != NULL || cmls_range != NULL) { + ERR(handle, "MLS is disabled, but MLS level/range " + "was found for user %s", cname); + goto err; + } + + /* If there are no errors, and this is a new user, add the user to policy */ + if (new) { + void *tmp_ptr; + + /* Ensure reverse lookup array has enough space */ + tmp_ptr = reallocarray(policydb->user_val_to_struct, + policydb->p_users.nprim + 1, + sizeof(user_datum_t *)); + if (!tmp_ptr) + goto omem; + policydb->user_val_to_struct = tmp_ptr; + policydb->user_val_to_struct[policydb->p_users.nprim] = NULL; + + tmp_ptr = reallocarray(policydb->sym_val_to_name[SYM_USERS], + policydb->p_users.nprim + 1, + sizeof(char *)); + if (!tmp_ptr) + goto omem; + policydb->sym_val_to_name[SYM_USERS] = tmp_ptr; + policydb->p_user_val_to_name[policydb->p_users.nprim] = NULL; + + /* Need to copy the user name */ + name = strdup(cname); + if (!name) + goto omem; + + /* Store user */ + usrdatum->s.value = ++policydb->p_users.nprim; + if (hashtab_insert(policydb->p_users.table, name, + (hashtab_datum_t) usrdatum) < 0) + goto omem; + + /* Set up reverse entry */ + policydb->p_user_val_to_name[usrdatum->s.value - 1] = name; + policydb->user_val_to_struct[usrdatum->s.value - 1] = usrdatum; + name = NULL; + + /* Expand roles */ + if (role_set_expand(&usrdatum->roles, &usrdatum->cache, + policydb, NULL, NULL)) { + ERR(handle, "unable to expand role set"); + goto err; + } + } + + free(roles); + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory"); + + err: + ERR(handle, "could not load %s into policy", name); + + free(name); + free(roles); + if (new && usrdatum) { + role_set_destroy(&usrdatum->roles); + free(usrdatum); + } + return STATUS_ERR; +} + +int sepol_user_exists(sepol_handle_t * handle __attribute__ ((unused)), + const sepol_policydb_t * p, + const sepol_user_key_t * key, int *response) +{ + + const policydb_t *policydb = &p->p; + + const char *cname; + sepol_user_key_unpack(key, &cname); + + *response = (hashtab_search(policydb->p_users.table, cname) != NULL); + + return STATUS_SUCCESS; +} + +int sepol_user_count(sepol_handle_t * handle __attribute__ ((unused)), + const sepol_policydb_t * p, unsigned int *response) +{ + + const policydb_t *policydb = &p->p; + *response = policydb->p_users.nprim; + + return STATUS_SUCCESS; +} + +int sepol_user_query(sepol_handle_t * handle, + const sepol_policydb_t * p, + const sepol_user_key_t * key, sepol_user_t ** response) +{ + + const policydb_t *policydb = &p->p; + user_datum_t *usrdatum = NULL; + + const char *cname; + sepol_user_key_unpack(key, &cname); + + usrdatum = hashtab_search(policydb->p_users.table, cname); + + if (!usrdatum) { + *response = NULL; + return STATUS_SUCCESS; + } + + if (user_to_record(handle, policydb, usrdatum->s.value - 1, response) < + 0) + goto err; + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not query user %s", cname); + return STATUS_ERR; +} + +int sepol_user_iterate(sepol_handle_t * handle, + const sepol_policydb_t * p, + int (*fn) (const sepol_user_t * user, + void *fn_arg), void *arg) +{ + + const policydb_t *policydb = &p->p; + unsigned int nusers = policydb->p_users.nprim; + sepol_user_t *user = NULL; + unsigned int i; + + /* For each user */ + for (i = 0; i < nusers; i++) { + + int status; + + if (user_to_record(handle, policydb, i, &user) < 0) + goto err; + + /* Invoke handler */ + status = fn(user, arg); + if (status < 0) + goto err; + + sepol_user_free(user); + user = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + + err: + ERR(handle, "could not iterate over users"); + sepol_user_free(user); + return STATUS_ERR; +} diff --git a/kernel/libsepol/src/users.o b/kernel/libsepol/src/users.o new file mode 100644 index 00000000..15e461fd Binary files /dev/null and b/kernel/libsepol/src/users.o differ diff --git a/kernel/libsepol/src/util.c b/kernel/libsepol/src/util.c new file mode 100644 index 00000000..9dc636cf --- /dev/null +++ b/kernel/libsepol/src/util.c @@ -0,0 +1,291 @@ +/* Authors: Joshua Brindle + * Jason Tang + * + * Copyright (C) 2005-2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// #include +#include +// #include +// #include +// #include + +#include +#include +#include + +#include "private.h" + +struct val_to_name { + unsigned int val; + char *name; +}; + +/* Add an unsigned integer to a dynamically reallocated array. *cnt + * is a reference pointer to the number of values already within array + * *a; it will be incremented upon successfully appending i. If *a is + * NULL then this function will create a new array (*cnt is reset to + * 0). Return 0 on success, -1 on out of memory. */ +int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a) +{ + uint32_t *new; + + if (cnt == NULL || a == NULL) + return -1; + + /* FIX ME: This is not very elegant! We use an array that we + * grow as new uint32_t are added to an array. But rather + * than be smart about it, for now we realloc() the array each + * time a new uint32_t is added! */ + if (*a != NULL) + new = (uint32_t *) reallocarray(*a, *cnt + 1, sizeof(uint32_t)); + else { /* empty list */ + + *cnt = 0; + new = (uint32_t *) malloc(sizeof(uint32_t)); + } + if (new == NULL) { + return -1; + } + new[*cnt] = i; + (*cnt)++; + *a = new; + return 0; +} + +static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + struct val_to_name *v = data; + perm_datum_t *perdatum; + + perdatum = (perm_datum_t *) datum; + + if (v->val == perdatum->s.value) { + v->name = key; + return 1; + } + + return 0; +} + +char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass, + sepol_access_vector_t av) +{ + struct val_to_name v; + static char avbuf[1024]; + class_datum_t *cladatum; + char *perm = NULL, *p; + unsigned int i; + int rc; + int avlen = 0, len; + + memset(avbuf, 0, sizeof avbuf); + cladatum = policydbp->class_val_to_struct[tclass - 1]; + p = avbuf; + for (i = 0; i < cladatum->permissions.nprim; i++) { + if (av & (UINT32_C(1) << i)) { + v.val = i + 1; + rc = ksu_hashtab_map(cladatum->permissions.table, + perm_name, &v); + if (!rc && cladatum->comdatum) { + rc = ksu_hashtab_map(cladatum->comdatum-> + permissions.table, perm_name, + &v); + } + if (rc) + perm = v.name; + if (perm) { + len = + snprintf(p, sizeof(avbuf) - avlen, " %s", + perm); + if (len < 0 + || (size_t) len >= (sizeof(avbuf) - avlen)) + return NULL; + p += len; + avlen += len; + } + } + } + + return avbuf; +} + +#define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p)) + +char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms) +{ + uint16_t value; + uint16_t low_bit; + uint16_t low_value; + unsigned int bit; + unsigned int in_range = 0; + static char xpermsbuf[2048]; + char *p; + int len, xpermslen = 0; + xpermsbuf[0] = '\0'; + p = xpermsbuf; + + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) + return NULL; + + len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "ioctl { "); + p += len; + xpermslen += len; + + for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { + if (!xperm_test(bit, xperms->perms)) + continue; + + if (in_range && next_bit_in_range(bit, xperms->perms)) { + /* continue until high value found */ + continue; + } else if (next_bit_in_range(bit, xperms->perms)) { + /* low value */ + low_bit = bit; + in_range = 1; + continue; + } + + if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { + value = xperms->driver<<8 | bit; + if (in_range) { + low_value = xperms->driver<<8 | low_bit; + len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, value); + } else { + len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx ", value); + } + } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { + value = bit << 8; + if (in_range) { + low_value = low_bit << 8; + len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff)); + } else { + len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff)); + } + + } + + if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen)) + return NULL; + + p += len; + xpermslen += len; + if (in_range) + in_range = 0; + } + + len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "}"); + if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen)) + return NULL; + + return xpermsbuf; +} + +/* + * The tokenize and tokenize_str functions may be used to + * replace sscanf to read tokens from buffers. + */ + +/* Read a token from a buffer */ +static inline int tokenize_str(char delim, char **str, char **ptr, size_t *len) +{ + char *tmp_buf = *ptr; + *str = NULL; + + while (**ptr != '\0') { + if (isspace(delim) && isspace(**ptr)) { + (*ptr)++; + break; + } else if (!isspace(delim) && **ptr == delim) { + (*ptr)++; + break; + } + + (*ptr)++; + } + + *len = *ptr - tmp_buf; + /* If the end of the string has not been reached, this will ensure the + * delimiter is not included when returning the token. + */ + if (**ptr != '\0') { + (*len)--; + } + + *str = strndup(tmp_buf, *len); + if (!*str) { + return -1; + } + + /* Squash spaces if the delimiter is a whitespace character */ + while (**ptr != '\0' && isspace(delim) && isspace(**ptr)) { + (*ptr)++; + } + + return 0; +} + +/* + * line_buf - Buffer containing string to tokenize. + * delim - The delimiter used to tokenize line_buf. A whitespace delimiter will + * be tokenized using isspace(). + * num_args - The number of parameter entries to process. + * ... - A 'char **' for each parameter. + * returns - The number of items processed. + * + * This function calls tokenize_str() to do the actual string processing. The + * caller is responsible for calling free() on each additional argument. The + * function will not tokenize more than num_args and the last argument will + * contain the remaining content of line_buf. If the delimiter is any whitespace + * character, then all whitespace will be squashed. + */ +int tokenize(char *line_buf, char delim, int num_args, ...) +{ + char **arg, *buf_p; + int rc, items; + size_t arg_len = 0; + va_list ap; + + buf_p = line_buf; + + /* Process the arguments */ + va_start(ap, num_args); + + for (items = 0; items < num_args && *buf_p != '\0'; items++) { + arg = va_arg(ap, char **); + + /* Save the remainder of the string in arg */ + if (items == num_args - 1) { + *arg = strdup(buf_p); + if (*arg == NULL) { + goto exit; + } + + continue; + } + + rc = tokenize_str(delim, arg, &buf_p, &arg_len); + if (rc < 0) { + goto exit; + } + } + +exit: + va_end(ap); + return items; +} diff --git a/kernel/libsepol/src/util.o b/kernel/libsepol/src/util.o new file mode 100644 index 00000000..36b11cfd Binary files /dev/null and b/kernel/libsepol/src/util.o differ diff --git a/kernel/libsepol/src/write.c b/kernel/libsepol/src/write.c new file mode 100644 index 00000000..fe09861d --- /dev/null +++ b/kernel/libsepol/src/write.c @@ -0,0 +1,2415 @@ + +/* Author : Stephen Smalley, */ + +/* + * Updated: Trusted Computer Solutions, Inc. + * + * Support for enhanced MLS infrastructure. + * + * Updated: Frank Mayer and Karl MacMillan + * + * Added conditional policy language extensions + * + * Updated: Joshua Brindle and Jason Tang + * + * Module writing support + * + * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. + * Copyright (C) 2003-2005 Tresys Technology, LLC + * Copyright (C) 2017 Mellanox Technologies Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +// #include +// #include + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "private.h" +#include "mls.h" + +#define glblub_version ((p->policy_type == POLICY_KERN && \ + p->policyvers >= POLICYDB_VERSION_GLBLUB) || \ + (p->policy_type == POLICY_BASE && \ + p->policyvers >= MOD_POLICYDB_VERSION_GLBLUB)) + +struct policy_data { + struct policy_file *fp; + struct policydb *p; +}; + +static int avrule_write_list(policydb_t *p, + avrule_t * avrules, struct policy_file *fp); + +static int ebitmap_write(ebitmap_t * e, struct policy_file *fp) +{ + ebitmap_node_t *n; + uint32_t buf[32], bit, count; + uint64_t map; + size_t items; + + buf[0] = cpu_to_le32(MAPSIZE); + buf[1] = cpu_to_le32(e->highbit); + + count = 0; + for (n = e->node; n; n = n->next) + count++; + buf[2] = cpu_to_le32(count); + + items = put_entry(buf, sizeof(uint32_t), 3, fp); + if (items != 3) + return POLICYDB_ERROR; + + for (n = e->node; n; n = n->next) { + bit = cpu_to_le32(n->startbit); + items = put_entry(&bit, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + map = cpu_to_le64(n->map); + items = put_entry(&map, sizeof(uint64_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + } + + return POLICYDB_SUCCESS; +} + +/* Ordering of datums in the original avtab format in the policy file. */ +static uint16_t spec_order[] = { + AVTAB_ALLOWED, + AVTAB_AUDITDENY, + AVTAB_AUDITALLOW, + AVTAB_TRANSITION, + AVTAB_CHANGE, + AVTAB_MEMBER +}; + +static int avtab_write_item(policydb_t * p, + avtab_ptr_t cur, struct policy_file *fp, + unsigned merge, unsigned commit, uint32_t * nel) +{ + avtab_ptr_t node; + uint8_t buf8; + uint16_t buf16[4]; + uint32_t buf32[10], lookup, val; + size_t items, items2; + unsigned set; + unsigned int oldvers = (p->policy_type == POLICY_KERN + && p->policyvers < POLICYDB_VERSION_AVTAB); + unsigned int i; + + if (oldvers) { + /* Generate the old avtab format. + Requires merging similar entries if uncond avtab. */ + if (merge) { + if (cur->merged) + return POLICYDB_SUCCESS; /* already merged by prior merge */ + } + + items = 1; /* item 0 is used for the item count */ + val = cur->key.source_type; + buf32[items++] = cpu_to_le32(val); + val = cur->key.target_type; + buf32[items++] = cpu_to_le32(val); + val = cur->key.target_class; + buf32[items++] = cpu_to_le32(val); + + val = cur->key.specified & ~AVTAB_ENABLED; + if (cur->key.specified & AVTAB_ENABLED) + val |= AVTAB_ENABLED_OLD; + set = 1; + + if (merge) { + /* Merge specifier values for all similar (av or type) + entries that have the same key. */ + if (val & AVTAB_AV) + lookup = AVTAB_AV; + else if (val & AVTAB_TYPE) + lookup = AVTAB_TYPE; + else + return POLICYDB_ERROR; + for (node = ksu_avtab_search_node_next(cur, lookup); + node; + node = ksu_avtab_search_node_next(node, lookup)) { + val |= (node->key.specified & ~AVTAB_ENABLED); + set++; + if (node->key.specified & AVTAB_ENABLED) + val |= AVTAB_ENABLED_OLD; + } + } + + if (!(val & (AVTAB_AV | AVTAB_TYPE))) { + ERR(fp->handle, "null entry"); + return POLICYDB_ERROR; + } + if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) { + ERR(fp->handle, "entry has both access " + "vectors and types"); + return POLICYDB_ERROR; + } + + buf32[items++] = cpu_to_le32(val); + + if (merge) { + /* Include datums for all similar (av or type) + entries that have the same key. */ + for (i = 0; + i < (sizeof(spec_order) / sizeof(spec_order[0])); + i++) { + if (val & spec_order[i]) { + if (cur->key.specified & spec_order[i]) + node = cur; + else { + node = + ksu_avtab_search_node_next(cur, + spec_order + [i]); + if (nel) + (*nel)--; /* one less node */ + } + + if (!node) { + ERR(fp->handle, "missing node"); + return POLICYDB_ERROR; + } + buf32[items++] = + cpu_to_le32(node->datum.data); + set--; + node->merged = 1; + } + } + } else { + buf32[items++] = cpu_to_le32(cur->datum.data); + cur->merged = 1; + set--; + } + + if (set) { + ERR(fp->handle, "data count wrong"); + return POLICYDB_ERROR; + } + + buf32[0] = cpu_to_le32(items - 1); + + if (commit) { + /* Commit this item to the policy file. */ + items2 = put_entry(buf32, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; + } + + /* Generate the new avtab format. */ + buf16[0] = cpu_to_le16(cur->key.source_type); + buf16[1] = cpu_to_le16(cur->key.target_type); + buf16[2] = cpu_to_le16(cur->key.target_class); + buf16[3] = cpu_to_le16(cur->key.specified); + items = put_entry(buf16, sizeof(uint16_t), 4, fp); + if (items != 4) + return POLICYDB_ERROR; + if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) && + (cur->key.specified & AVTAB_XPERMS)) { + ERR(fp->handle, "policy version %u does not support ioctl extended" + "permissions rules and one was specified", p->policyvers); + return POLICYDB_ERROR; + } + + if (p->target_platform != SEPOL_TARGET_SELINUX && + (cur->key.specified & AVTAB_XPERMS)) { + ERR(fp->handle, "Target platform %s does not support ioctl " + "extended permissions rules and one was specified", + policydb_target_strings[p->target_platform]); + return POLICYDB_ERROR; + } + + if (cur->key.specified & AVTAB_XPERMS) { + buf8 = cur->datum.xperms->specified; + items = put_entry(&buf8, sizeof(uint8_t),1,fp); + if (items != 1) + return POLICYDB_ERROR; + buf8 = cur->datum.xperms->driver; + items = put_entry(&buf8, sizeof(uint8_t),1,fp); + if (items != 1) + return POLICYDB_ERROR; + for (i = 0; i < ARRAY_SIZE(cur->datum.xperms->perms); i++) + buf32[i] = cpu_to_le32(cur->datum.xperms->perms[i]); + items = put_entry(buf32, sizeof(uint32_t),8,fp); + if (items != 8) + return POLICYDB_ERROR; + } else { + buf32[0] = cpu_to_le32(cur->datum.data); + items = put_entry(buf32, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + +static inline void avtab_reset_merged(avtab_t * a) +{ + unsigned int i; + avtab_ptr_t cur; + for (i = 0; i < a->nslot; i++) { + for (cur = a->htable[i]; cur; cur = cur->next) + cur->merged = 0; + } +} + +static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) +{ + unsigned int i; + int rc; + avtab_t expa; + avtab_ptr_t cur; + uint32_t nel; + size_t items; + unsigned int oldvers = (p->policy_type == POLICY_KERN + && p->policyvers < POLICYDB_VERSION_AVTAB); + + if (oldvers) { + /* Old avtab format. + First, we need to expand attributes. Then, we need to + merge similar entries, so we need to track merged nodes + and compute the final nel. */ + if (ksu_avtab_init(&expa)) + return POLICYDB_ERROR; + if (expand_avtab(p, a, &expa)) { + rc = -1; + goto out; + } + a = &expa; + avtab_reset_merged(a); + nel = a->nel; + } else { + /* New avtab format. nel is good to go. */ + nel = cpu_to_le32(a->nel); + items = put_entry(&nel, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + + for (i = 0; i < a->nslot; i++) { + for (cur = a->htable[i]; cur; cur = cur->next) { + /* If old format, compute final nel. + If new format, write out the items. */ + if (avtab_write_item(p, cur, fp, 1, !oldvers, &nel)) { + rc = -1; + goto out; + } + } + } + + if (oldvers) { + /* Old avtab format. + Write the computed nel value, then write the items. */ + nel = cpu_to_le32(nel); + items = put_entry(&nel, sizeof(uint32_t), 1, fp); + if (items != 1) { + rc = -1; + goto out; + } + avtab_reset_merged(a); + for (i = 0; i < a->nslot; i++) { + for (cur = a->htable[i]; cur; cur = cur->next) { + if (avtab_write_item(p, cur, fp, 1, 1, NULL)) { + rc = -1; + goto out; + } + } + } + } + + rc = 0; + out: + if (oldvers) + ksu_avtab_destroy(&expa); + return rc; +} + +/* + * Write a semantic MLS level structure to a policydb binary + * representation file. + */ +static int mls_write_semantic_level_helper(mls_semantic_level_t * l, + struct policy_file *fp) +{ + uint32_t buf[2], ncat = 0; + size_t items; + mls_semantic_cat_t *cat; + + for (cat = l->cat; cat; cat = cat->next) + ncat++; + + buf[0] = cpu_to_le32(l->sens); + buf[1] = cpu_to_le32(ncat); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + + for (cat = l->cat; cat; cat = cat->next) { + buf[0] = cpu_to_le32(cat->low); + buf[1] = cpu_to_le32(cat->high); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + +/* + * Read a semantic MLS range structure to a policydb binary + * representation file. + */ +static int mls_write_semantic_range_helper(mls_semantic_range_t * r, + struct policy_file *fp) +{ + int rc; + + rc = mls_write_semantic_level_helper(&r->level[0], fp); + if (rc) + return rc; + + rc = mls_write_semantic_level_helper(&r->level[1], fp); + + return rc; +} + +/* + * Write a MLS level structure to a policydb binary + * representation file. + */ +static int mls_write_level(mls_level_t * l, struct policy_file *fp) +{ + uint32_t sens; + size_t items; + + sens = cpu_to_le32(l->sens); + items = put_entry(&sens, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + if (ebitmap_write(&l->cat, fp)) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +/* + * Write a MLS range structure to a policydb binary + * representation file. + */ +static int mls_write_range_helper(mls_range_t * r, struct policy_file *fp) +{ + uint32_t buf[3]; + size_t items, items2; + int eq; + + eq = mls_level_eq(&r->level[1], &r->level[0]); + + items = 1; /* item 0 is used for the item count */ + buf[items++] = cpu_to_le32(r->level[0].sens); + if (!eq) + buf[items++] = cpu_to_le32(r->level[1].sens); + buf[0] = cpu_to_le32(items - 1); + + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items2 != items) + return POLICYDB_ERROR; + + if (ebitmap_write(&r->level[0].cat, fp)) + return POLICYDB_ERROR; + if (!eq) + if (ebitmap_write(&r->level[1].cat, fp)) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int sens_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + level_datum_t *levdatum; + uint32_t buf[32]; + size_t items, items2, len; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + + levdatum = (level_datum_t *) datum; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(levdatum->isalias); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (mls_write_level(levdatum->level, fp)) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int cat_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + cat_datum_t *catdatum; + uint32_t buf[32]; + size_t items, items2, len; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + + catdatum = (cat_datum_t *) datum; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(catdatum->s.value); + buf[items++] = cpu_to_le32(catdatum->isalias); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int role_trans_write(policydb_t *p, struct policy_file *fp) +{ + role_trans_t *r = p->role_tr; + role_trans_t *tr; + uint32_t buf[3]; + size_t nel, items; + int new_roletr = (p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_ROLETRANS); + int warning_issued = 0; + + nel = 0; + for (tr = r; tr; tr = tr->next) + if(new_roletr || tr->tclass == p->process_class) + nel++; + + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (tr = r; tr; tr = tr->next) { + if (!new_roletr && tr->tclass != p->process_class) { + if (!warning_issued) + WARN(fp->handle, "Discarding role_transition " + "rules for security classes other than " + "\"process\""); + warning_issued = 1; + continue; + } + buf[0] = cpu_to_le32(tr->role); + buf[1] = cpu_to_le32(tr->type); + buf[2] = cpu_to_le32(tr->new_role); + items = put_entry(buf, sizeof(uint32_t), 3, fp); + if (items != 3) + return POLICYDB_ERROR; + if (new_roletr) { + buf[0] = cpu_to_le32(tr->tclass); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + } + + return POLICYDB_SUCCESS; +} + +static int role_allow_write(role_allow_t * r, struct policy_file *fp) +{ + role_allow_t *ra; + uint32_t buf[2]; + size_t nel, items; + + nel = 0; + for (ra = r; ra; ra = ra->next) + nel++; + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (ra = r; ra; ra = ra->next) { + buf[0] = cpu_to_le32(ra->role); + buf[1] = cpu_to_le32(ra->new_role); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; +} + +static int filename_write_one_compat(hashtab_key_t key, void *data, void *ptr) +{ + uint32_t bit, buf[4]; + size_t items, len; + filename_trans_key_t *ft = (filename_trans_key_t *)key; + filename_trans_datum_t *datum = data; + ebitmap_node_t *node; + void *fp = ptr; + + len = strlen(ft->name); + do { + ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + items = put_entry(ft->name, sizeof(char), len, fp); + if (items != len) + return POLICYDB_ERROR; + + buf[0] = cpu_to_le32(bit + 1); + buf[1] = cpu_to_le32(ft->ttype); + buf[2] = cpu_to_le32(ft->tclass); + buf[3] = cpu_to_le32(datum->otype); + items = put_entry(buf, sizeof(uint32_t), 4, fp); + if (items != 4) + return POLICYDB_ERROR; + } + + datum = datum->next; + } while (datum); + + return 0; +} + +static int filename_write_one(hashtab_key_t key, void *data, void *ptr) +{ + uint32_t buf[3]; + size_t items, len, ndatum; + filename_trans_key_t *ft = (filename_trans_key_t *)key; + filename_trans_datum_t *datum; + void *fp = ptr; + + len = strlen(ft->name); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + items = put_entry(ft->name, sizeof(char), len, fp); + if (items != len) + return POLICYDB_ERROR; + + ndatum = 0; + datum = data; + do { + ndatum++; + datum = datum->next; + } while (datum); + + buf[0] = cpu_to_le32(ft->ttype); + buf[1] = cpu_to_le32(ft->tclass); + buf[2] = cpu_to_le32(ndatum); + items = put_entry(buf, sizeof(uint32_t), 3, fp); + if (items != 3) + return POLICYDB_ERROR; + + datum = data; + do { + if (ebitmap_write(&datum->stypes, fp)) + return POLICYDB_ERROR; + + buf[0] = cpu_to_le32(datum->otype); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + datum = datum->next; + } while (datum); + + return 0; +} + +static int filename_trans_write(struct policydb *p, void *fp) +{ + size_t items; + uint32_t buf[1]; + int rc; + + if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS) + return 0; + + if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { + buf[0] = cpu_to_le32(p->filename_trans_count); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + rc = ksu_hashtab_map(p->filename_trans, filename_write_one_compat, + fp); + } else { + buf[0] = cpu_to_le32(p->filename_trans->nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + rc = ksu_hashtab_map(p->filename_trans, filename_write_one, fp); + } + return rc; +} + +static int role_set_write(role_set_t * x, struct policy_file *fp) +{ + size_t items; + uint32_t buf[1]; + + if (ebitmap_write(&x->roles, fp)) + return POLICYDB_ERROR; + + buf[0] = cpu_to_le32(x->flags); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int type_set_write(type_set_t * x, struct policy_file *fp) +{ + size_t items; + uint32_t buf[1]; + + if (ebitmap_write(&x->types, fp)) + return POLICYDB_ERROR; + if (ebitmap_write(&x->negset, fp)) + return POLICYDB_ERROR; + + buf[0] = cpu_to_le32(x->flags); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + cond_bool_datum_t *booldatum; + uint32_t buf[3], len; + unsigned int items, items2; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + struct policydb *p = pd->p; + + booldatum = (cond_bool_datum_t *) datum; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(booldatum->s.value); + buf[items++] = cpu_to_le32(booldatum->state); + buf[items++] = cpu_to_le32(len); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (p->policy_type != POLICY_KERN && + p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { + buf[0] = cpu_to_le32(booldatum->flags); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + +/* + * cond_write_cond_av_list doesn't write out the av_list nodes. + * Instead it writes out the key/value pairs from the avtab. This + * is necessary because there is no way to uniquely identifying rules + * in the avtab so it is not possible to associate individual rules + * in the avtab with a conditional without saving them as part of + * the conditional. This means that the avtab with the conditional + * rules will not be saved but will be rebuilt on policy load. + */ +static int cond_write_av_list(policydb_t * p, + cond_av_list_t * list, struct policy_file *fp) +{ + uint32_t buf[4]; + cond_av_list_t *cur_list, *new_list = NULL; + avtab_t expa; + uint32_t len, items; + unsigned int oldvers = (p->policy_type == POLICY_KERN + && p->policyvers < POLICYDB_VERSION_AVTAB); + int rc = -1; + + if (oldvers) { + if (ksu_avtab_init(&expa)) + return POLICYDB_ERROR; + if (expand_cond_av_list(p, list, &new_list, &expa)) + goto out; + list = new_list; + } + + len = 0; + for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { + if (cur_list->node->parse_context) + len++; + } + + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + goto out; + + if (len == 0) { + rc = 0; + goto out; + } + + for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { + if (cur_list->node->parse_context) + if (avtab_write_item(p, cur_list->node, fp, 0, 1, NULL)) + goto out; + } + + rc = 0; + out: + if (oldvers) { + cond_av_list_destroy(new_list); + ksu_avtab_destroy(&expa); + } + + return rc; +} + +static int cond_write_node(policydb_t * p, + cond_node_t * node, struct policy_file *fp) +{ + cond_expr_t *cur_expr; + uint32_t buf[2]; + uint32_t items, items2, len; + + buf[0] = cpu_to_le32(node->cur_state); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + /* expr */ + len = 0; + for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) + len++; + + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) { + items = 0; + buf[items++] = cpu_to_le32(cur_expr->expr_type); + buf[items++] = cpu_to_le32(cur_expr->bool); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items2 != items) + return POLICYDB_ERROR; + } + + if (p->policy_type == POLICY_KERN) { + if (cond_write_av_list(p, node->true_list, fp) != 0) + return POLICYDB_ERROR; + if (cond_write_av_list(p, node->false_list, fp) != 0) + return POLICYDB_ERROR; + } else { + if (avrule_write_list(p, node->avtrue_list, fp)) + return POLICYDB_ERROR; + if (avrule_write_list(p, node->avfalse_list, fp)) + return POLICYDB_ERROR; + } + + if (p->policy_type != POLICY_KERN && + p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { + buf[0] = cpu_to_le32(node->flags); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + +static int cond_write_list(policydb_t * p, cond_list_t * list, + struct policy_file *fp) +{ + cond_node_t *cur; + uint32_t len, items; + uint32_t buf[1]; + + len = 0; + for (cur = list; cur != NULL; cur = cur->next) + len++; + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + for (cur = list; cur != NULL; cur = cur->next) { + if (cond_write_node(p, cur, fp) != 0) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; +} + +/* + * Write a security context structure + * to a policydb binary representation file. + */ +static int context_write(struct policydb *p, context_struct_t * c, + struct policy_file *fp) +{ + uint32_t buf[32]; + size_t items, items2; + + items = 0; + buf[items++] = cpu_to_le32(c->user); + buf[items++] = cpu_to_le32(c->role); + buf[items++] = cpu_to_le32(c->type); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items2 != items) + return POLICYDB_ERROR; + if ((p->policyvers >= POLICYDB_VERSION_MLS + && p->policy_type == POLICY_KERN) + || (p->policyvers >= MOD_POLICYDB_VERSION_MLS + && p->policy_type == POLICY_BASE)) + if (mls_write_range_helper(&c->range, fp)) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +/* + * The following *_write functions are used to + * write the symbol data to a policy database + * binary representation file. + */ + +static int perm_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + perm_datum_t *perdatum; + uint32_t buf[32]; + size_t items, items2, len; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + + perdatum = (perm_datum_t *) datum; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(perdatum->s.value); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int common_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + common_datum_t *comdatum; + uint32_t buf[32]; + size_t items, items2, len; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + + comdatum = (common_datum_t *) datum; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(comdatum->s.value); + buf[items++] = cpu_to_le32(comdatum->permissions.nprim); + buf[items++] = cpu_to_le32(comdatum->permissions.table->nel); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (ksu_hashtab_map(comdatum->permissions.table, perm_write, pd)) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int write_cons_helper(policydb_t * p, + constraint_node_t * node, int allowxtarget, + struct policy_file *fp) +{ + constraint_node_t *c; + constraint_expr_t *e; + uint32_t buf[3], nexpr; + int items; + + for (c = node; c; c = c->next) { + nexpr = 0; + for (e = c->expr; e; e = e->next) { + nexpr++; + } + buf[0] = cpu_to_le32(c->permissions); + buf[1] = cpu_to_le32(nexpr); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + for (e = c->expr; e; e = e->next) { + buf[0] = cpu_to_le32(e->expr_type); + buf[1] = cpu_to_le32(e->attr); + buf[2] = cpu_to_le32(e->op); + items = put_entry(buf, sizeof(uint32_t), 3, fp); + if (items != 3) + return POLICYDB_ERROR; + + switch (e->expr_type) { + case CEXPR_NAMES: + if (!allowxtarget && (e->attr & CEXPR_XTARGET)) + return POLICYDB_ERROR; + if (ebitmap_write(&e->names, fp)) { + return POLICYDB_ERROR; + } + if ((p->policy_type != POLICY_KERN && + type_set_write(e->type_names, fp)) || + (p->policy_type == POLICY_KERN && + (p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) && + type_set_write(e->type_names, fp))) { + return POLICYDB_ERROR; + } + break; + default: + break; + } + } + } + + return POLICYDB_SUCCESS; +} + +static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + class_datum_t *cladatum; + constraint_node_t *c; + uint32_t buf[32], ncons; + size_t items, items2, len, len2; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + struct policydb *p = pd->p; + + cladatum = (class_datum_t *) datum; + + len = strlen(key); + if (cladatum->comkey) + len2 = strlen(cladatum->comkey); + else + len2 = 0; + + ncons = 0; + for (c = cladatum->constraints; c; c = c->next) { + ncons++; + } + + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(len2); + buf[items++] = cpu_to_le32(cladatum->s.value); + buf[items++] = cpu_to_le32(cladatum->permissions.nprim); + if (cladatum->permissions.table) + buf[items++] = cpu_to_le32(cladatum->permissions.table->nel); + else + buf[items++] = 0; + buf[items++] = cpu_to_le32(ncons); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (cladatum->comkey) { + items = put_entry(cladatum->comkey, 1, len2, fp); + if (items != len2) + return POLICYDB_ERROR; + } + if (ksu_hashtab_map(cladatum->permissions.table, perm_write, pd)) + return POLICYDB_ERROR; + + if (write_cons_helper(p, cladatum->constraints, 0, fp)) + return POLICYDB_ERROR; + + if ((p->policy_type == POLICY_KERN + && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) + || (p->policy_type == POLICY_BASE + && p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { + /* write out the validatetrans rule */ + ncons = 0; + for (c = cladatum->validatetrans; c; c = c->next) { + ncons++; + } + buf[0] = cpu_to_le32(ncons); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + if (write_cons_helper(p, cladatum->validatetrans, 1, fp)) + return POLICYDB_ERROR; + } + + if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { + buf[0] = cpu_to_le32(cladatum->default_user); + buf[1] = cpu_to_le32(cladatum->default_role); + if (!glblub_version && cladatum->default_range == DEFAULT_GLBLUB) { + WARN(fp->handle, + "class %s default_range set to GLBLUB but policy version is %d (%d required), discarding", + p->p_class_val_to_name[cladatum->s.value - 1], p->policyvers, + p->policy_type == POLICY_KERN? POLICYDB_VERSION_GLBLUB:MOD_POLICYDB_VERSION_GLBLUB); + cladatum->default_range = 0; + } + buf[2] = cpu_to_le32(cladatum->default_range); + items = put_entry(buf, sizeof(uint32_t), 3, fp); + if (items != 3) + return POLICYDB_ERROR; + } + + if ((p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) || + (p->policy_type == POLICY_BASE && + p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) { + buf[0] = cpu_to_le32(cladatum->default_type); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + +static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + role_datum_t *role; + uint32_t buf[32]; + size_t items, items2, len; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + struct policydb *p = pd->p; + + role = (role_datum_t *) datum; + + /* + * Role attributes are redundant for policy.X, skip them + * when writing the roles symbol table. They are also skipped + * when pp is downgraded. + * + * Their numbers would be deducted in ksu_policydb_write(). + */ + if ((role->flavor == ROLE_ATTRIB) && + ((p->policy_type == POLICY_KERN) || + (p->policy_type != POLICY_KERN && + p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) + return POLICYDB_SUCCESS; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(role->s.value); + if (policydb_has_boundary_feature(p)) + buf[items++] = cpu_to_le32(role->bounds); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (ebitmap_write(&role->dominates, fp)) + return POLICYDB_ERROR; + if (p->policy_type == POLICY_KERN) { + if (role->s.value == OBJECT_R_VAL) { + /* + * CIL populates object_r's types map + * rather than handling it as a special case. + * However, this creates an inconsistency with + * the kernel policy read from /sys/fs/selinux/policy + * because the kernel ignores everything except for + * object_r's value from the policy file. + * Make them consistent by writing an empty + * ebitmap instead. + */ + ebitmap_t empty; + ebitmap_init(&empty); + if (ebitmap_write(&empty, fp)) + return POLICYDB_ERROR; + } else { + if (ebitmap_write(&role->types.types, fp)) + return POLICYDB_ERROR; + } + } else { + if (type_set_write(&role->types, fp)) + return POLICYDB_ERROR; + } + + if (p->policy_type != POLICY_KERN && + p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) { + buf[0] = cpu_to_le32(role->flavor); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + if (ebitmap_write(&role->roles, fp)) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + +static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + type_datum_t *typdatum; + uint32_t buf[32]; + size_t items, items2, len; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + struct policydb *p = pd->p; + + typdatum = (type_datum_t *) datum; + + /* + * The kernel policy version less than 24 (= POLICYDB_VERSION_BOUNDARY) + * does not support to load entries of attribute, so we skip to write it. + */ + if (p->policy_type == POLICY_KERN + && p->policyvers < POLICYDB_VERSION_BOUNDARY + && typdatum->flavor == TYPE_ATTRIB) + return POLICYDB_SUCCESS; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(typdatum->s.value); + if (policydb_has_boundary_feature(p)) { + uint32_t properties = 0; + + if (p->policy_type != POLICY_KERN + && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) { + buf[items++] = cpu_to_le32(typdatum->primary); + } + + if (typdatum->primary) + properties |= TYPEDATUM_PROPERTY_PRIMARY; + + if (typdatum->flavor == TYPE_ATTRIB) { + properties |= TYPEDATUM_PROPERTY_ATTRIBUTE; + } else if (typdatum->flavor == TYPE_ALIAS + && p->policy_type != POLICY_KERN) + properties |= TYPEDATUM_PROPERTY_ALIAS; + + if (typdatum->flags & TYPE_FLAGS_PERMISSIVE + && p->policy_type != POLICY_KERN) + properties |= TYPEDATUM_PROPERTY_PERMISSIVE; + + buf[items++] = cpu_to_le32(properties); + buf[items++] = cpu_to_le32(typdatum->bounds); + } else { + buf[items++] = cpu_to_le32(typdatum->primary); + + if (p->policy_type != POLICY_KERN) { + buf[items++] = cpu_to_le32(typdatum->flavor); + + if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) + buf[items++] = cpu_to_le32(typdatum->flags); + else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE) + WARN(fp->handle, "Warning! Module policy " + "version %d cannot support permissive " + "types, but one was defined", + p->policyvers); + } + } + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + if (p->policy_type != POLICY_KERN) { + if (ebitmap_write(&typdatum->types, fp)) + return POLICYDB_ERROR; + } + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + return POLICYDB_SUCCESS; +} + +static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + user_datum_t *usrdatum; + uint32_t buf[32]; + size_t items, items2, len; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + struct policydb *p = pd->p; + + usrdatum = (user_datum_t *) datum; + + len = strlen(key); + items = 0; + buf[items++] = cpu_to_le32(len); + buf[items++] = cpu_to_le32(usrdatum->s.value); + if (policydb_has_boundary_feature(p)) + buf[items++] = cpu_to_le32(usrdatum->bounds); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + items = put_entry(key, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (p->policy_type == POLICY_KERN) { + if (ebitmap_write(&usrdatum->roles.roles, fp)) + return POLICYDB_ERROR; + } else { + if (role_set_write(&usrdatum->roles, fp)) + return POLICYDB_ERROR; + } + + if ((p->policyvers >= POLICYDB_VERSION_MLS + && p->policy_type == POLICY_KERN) + || (p->policyvers >= MOD_POLICYDB_VERSION_MLS + && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS + && p->policy_type == POLICY_MOD) + || (p->policyvers >= MOD_POLICYDB_VERSION_MLS + && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS + && p->policy_type == POLICY_BASE)) { + if (mls_write_range_helper(&usrdatum->exp_range, fp)) + return POLICYDB_ERROR; + if (mls_write_level(&usrdatum->exp_dfltlevel, fp)) + return POLICYDB_ERROR; + } else if ((p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS + && p->policy_type == POLICY_MOD) + || (p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS + && p->policy_type == POLICY_BASE)) { + if (mls_write_semantic_range_helper(&usrdatum->range, fp)) + return -1; + if (mls_write_semantic_level_helper(&usrdatum->dfltlevel, fp)) + return -1; + } + + return POLICYDB_SUCCESS; +} + +static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, + void *datap) = { +common_write, class_write, role_write, type_write, user_write, + cond_write_bool, sens_write, cat_write,}; + +static int ocontext_write_xen(const struct policydb_compat_info *info, policydb_t *p, + struct policy_file *fp) +{ + unsigned int i, j; + size_t nel, items, len; + uint32_t buf[32]; + ocontext_t *c; + for (i = 0; i < info->ocon_num; i++) { + nel = 0; + for (c = p->ocontexts[i]; c; c = c->next) { + if (i == OCON_XEN_ISID && !c->context[0].user) { + INFO(fp->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } + nel++; + } + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (c = p->ocontexts[i]; c; c = c->next) { + switch (i) { + case OCON_XEN_ISID: + if (!c->context[0].user) + break; + buf[0] = cpu_to_le32(c->sid[0]); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_XEN_PIRQ: + buf[0] = cpu_to_le32(c->u.pirq); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_XEN_IOPORT: + buf[0] = c->u.ioport.low_ioport; + buf[1] = c->u.ioport.high_ioport; + for (j = 0; j < 2; j++) + buf[j] = cpu_to_le32(buf[j]); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_XEN_IOMEM: + if (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) { + uint64_t b64[2]; + b64[0] = c->u.iomem.low_iomem; + b64[1] = c->u.iomem.high_iomem; + for (j = 0; j < 2; j++) + b64[j] = cpu_to_le64(b64[j]); + items = put_entry(b64, sizeof(uint64_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + } else { + if (c->u.iomem.high_iomem > 0xFFFFFFFFULL) { + ERR(fp->handle, "policy version %d" + " cannot represent IOMEM addresses over 16TB", + p->policyvers); + return POLICYDB_ERROR; + } + + buf[0] = c->u.iomem.low_iomem; + buf[1] = c->u.iomem.high_iomem; + for (j = 0; j < 2; j++) + buf[j] = cpu_to_le32(buf[j]); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + } + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_XEN_PCIDEVICE: + buf[0] = cpu_to_le32(c->u.device); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_XEN_DEVICETREE: + len = strlen(c->u.name); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + items = put_entry(c->u.name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + } + } + } + return POLICYDB_SUCCESS; +} + +static int ocontext_write_selinux(const struct policydb_compat_info *info, + policydb_t *p, struct policy_file *fp) +{ + unsigned int i, j; + size_t nel, items, len; + uint32_t buf[32]; + ocontext_t *c; + for (i = 0; i < info->ocon_num; i++) { + nel = 0; + for (c = p->ocontexts[i]; c; c = c->next) { + if (i == OCON_ISID && !c->context[0].user) { + INFO(fp->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } + nel++; + } + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (c = p->ocontexts[i]; c; c = c->next) { + switch (i) { + case OCON_ISID: + if (!c->context[0].user) + break; + buf[0] = cpu_to_le32(c->sid[0]); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_FS: + case OCON_NETIF: + len = strlen(c->u.name); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + items = put_entry(c->u.name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + if (context_write(p, &c->context[1], fp)) + return POLICYDB_ERROR; + break; + case OCON_IBPKEY: + /* The subnet prefix is in network order */ + memcpy(buf, &c->u.ibpkey.subnet_prefix, + sizeof(c->u.ibpkey.subnet_prefix)); + + buf[2] = cpu_to_le32(c->u.ibpkey.low_pkey); + buf[3] = cpu_to_le32(c->u.ibpkey.high_pkey); + + items = put_entry(buf, sizeof(uint32_t), 4, fp); + if (items != 4) + return POLICYDB_ERROR; + + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_IBENDPORT: + len = strlen(c->u.ibendport.dev_name); + buf[0] = cpu_to_le32(len); + buf[1] = cpu_to_le32(c->u.ibendport.port); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + items = put_entry(c->u.ibendport.dev_name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_PORT: + buf[0] = c->u.port.protocol; + buf[1] = c->u.port.low_port; + buf[2] = c->u.port.high_port; + for (j = 0; j < 3; j++) { + buf[j] = cpu_to_le32(buf[j]); + } + items = put_entry(buf, sizeof(uint32_t), 3, fp); + if (items != 3) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_NODE: + buf[0] = c->u.node.addr; /* network order */ + buf[1] = c->u.node.mask; /* network order */ + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_FSUSE: + buf[0] = cpu_to_le32(c->v.behavior); + len = strlen(c->u.name); + buf[1] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + items = put_entry(c->u.name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_NODE6: + for (j = 0; j < 4; j++) + buf[j] = c->u.node6.addr[j]; /* network order */ + for (j = 0; j < 4; j++) + buf[j + 4] = c->u.node6.mask[j]; /* network order */ + items = put_entry(buf, sizeof(uint32_t), 8, fp); + if (items != 8) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + } + } + } + return POLICYDB_SUCCESS; +} + +static int ocontext_write(const struct policydb_compat_info *info, policydb_t * p, + struct policy_file *fp) +{ + int rc = POLICYDB_ERROR; + switch (p->target_platform) { + case SEPOL_TARGET_SELINUX: + rc = ocontext_write_selinux(info, p, fp); + break; + case SEPOL_TARGET_XEN: + rc = ocontext_write_xen(info, p, fp); + break; + } + return rc; +} + +static int genfs_write(policydb_t * p, struct policy_file *fp) +{ + genfs_t *genfs; + ocontext_t *c; + size_t nel = 0, items, len; + uint32_t buf[32]; + + for (genfs = p->genfs; genfs; genfs = genfs->next) + nel++; + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (genfs = p->genfs; genfs; genfs = genfs->next) { + len = strlen(genfs->fstype); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + items = put_entry(genfs->fstype, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + nel = 0; + for (c = genfs->head; c; c = c->next) + nel++; + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (c = genfs->head; c; c = c->next) { + len = strlen(c->u.name); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + items = put_entry(c->u.name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + buf[0] = cpu_to_le32(c->v.sclass); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + } + } + return POLICYDB_SUCCESS; +} + + +struct rangetrans_write_args { + size_t nel; + int new_rangetr; + struct policy_file *fp; + struct policydb *p; +}; + +static int rangetrans_count(hashtab_key_t key, + void *data __attribute__ ((unused)), + void *ptr) +{ + struct range_trans *rt = (struct range_trans *)key; + struct rangetrans_write_args *args = ptr; + struct policydb *p = args->p; + + /* all range_transitions are written for the new format, only + process related range_transitions are written for the old + format, so count accordingly */ + if (args->new_rangetr || rt->target_class == p->process_class) + args->nel++; + return 0; +} + +static int range_write_helper(hashtab_key_t key, void *data, void *ptr) +{ + uint32_t buf[2]; + struct range_trans *rt = (struct range_trans *)key; + struct mls_range *r = data; + struct rangetrans_write_args *args = ptr; + struct policy_file *fp = args->fp; + struct policydb *p = args->p; + int new_rangetr = args->new_rangetr; + size_t items; + static int warning_issued = 0; + int rc; + + if (!new_rangetr && rt->target_class != p->process_class) { + if (!warning_issued) + WARN(fp->handle, "Discarding range_transition " + "rules for security classes other than " + "\"process\""); + warning_issued = 1; + return 0; + } + + buf[0] = cpu_to_le32(rt->source_type); + buf[1] = cpu_to_le32(rt->target_type); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + if (new_rangetr) { + buf[0] = cpu_to_le32(rt->target_class); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + rc = mls_write_range_helper(r, fp); + if (rc) + return rc; + + return 0; +} + +static int range_write(policydb_t * p, struct policy_file *fp) +{ + size_t items; + uint32_t buf[2]; + int new_rangetr = (p->policy_type == POLICY_KERN && + p->policyvers >= POLICYDB_VERSION_RANGETRANS); + struct rangetrans_write_args args; + int rc; + + args.nel = 0; + args.new_rangetr = new_rangetr; + args.fp = fp; + args.p = p; + rc = ksu_hashtab_map(p->range_tr, rangetrans_count, &args); + if (rc) + return rc; + + buf[0] = cpu_to_le32(args.nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + return ksu_hashtab_map(p->range_tr, range_write_helper, &args); +} + +/************** module writing functions below **************/ + +static int avrule_write(policydb_t *p, avrule_t * avrule, + struct policy_file *fp) +{ + size_t items, items2; + uint32_t buf[32], len; + class_perm_node_t *cur; + + if (p->policyvers < MOD_POLICYDB_VERSION_SELF_TYPETRANS && + (avrule->specified & AVRULE_TYPE) && + (avrule->flags & RULE_SELF)) { + ERR(fp->handle, + "Module contains a self rule not supported by the target module policy version"); + return POLICYDB_ERROR; + } + + items = 0; + buf[items++] = cpu_to_le32(avrule->specified); + buf[items++] = cpu_to_le32(avrule->flags); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items2 != items) + return POLICYDB_ERROR; + + if (type_set_write(&avrule->stypes, fp)) + return POLICYDB_ERROR; + + if (type_set_write(&avrule->ttypes, fp)) + return POLICYDB_ERROR; + + cur = avrule->perms; + len = 0; + while (cur) { + len++; + cur = cur->next; + } + items = 0; + buf[items++] = cpu_to_le32(len); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items2 != items) + return POLICYDB_ERROR; + cur = avrule->perms; + while (cur) { + items = 0; + buf[items++] = cpu_to_le32(cur->tclass); + buf[items++] = cpu_to_le32(cur->data); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items2 != items) + return POLICYDB_ERROR; + + cur = cur->next; + } + + if (avrule->specified & AVRULE_XPERMS) { + size_t nel = ARRAY_SIZE(avrule->xperms->perms); + uint32_t buf32[nel]; + uint8_t buf8; + unsigned int i; + + if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { + ERR(fp->handle, + "module policy version %u does not support ioctl" + " extended permissions rules and one was specified", + p->policyvers); + return POLICYDB_ERROR; + } + + if (p->target_platform != SEPOL_TARGET_SELINUX) { + ERR(fp->handle, + "Target platform %s does not support ioctl" + " extended permissions rules and one was specified", + policydb_target_strings[p->target_platform]); + return POLICYDB_ERROR; + } + + buf8 = avrule->xperms->specified; + items = put_entry(&buf8, sizeof(uint8_t),1,fp); + if (items != 1) + return POLICYDB_ERROR; + buf8 = avrule->xperms->driver; + items = put_entry(&buf8, sizeof(uint8_t),1,fp); + if (items != 1) + return POLICYDB_ERROR; + for (i = 0; i < nel; i++) + buf32[i] = cpu_to_le32(avrule->xperms->perms[i]); + items = put_entry(buf32, sizeof(uint32_t), nel, fp); + if (items != nel) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + +static int avrule_write_list(policydb_t *p, avrule_t * avrules, + struct policy_file *fp) +{ + uint32_t buf[32], len; + avrule_t *avrule; + + avrule = avrules; + len = 0; + while (avrule) { + len++; + avrule = avrule->next; + } + + buf[0] = cpu_to_le32(len); + if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) + return POLICYDB_ERROR; + + avrule = avrules; + while (avrule) { + if (avrule_write(p, avrule, fp)) + return POLICYDB_ERROR; + avrule = avrule->next; + } + + return POLICYDB_SUCCESS; +} + +static int only_process(ebitmap_t *in, struct policydb *p) +{ + unsigned int i, value; + ebitmap_node_t *node; + + if (!p->process_class) + return 0; + + value = p->process_class - 1; + + ebitmap_for_each_positive_bit(in, node, i) { + if (i != value) + return 0; + } + return 1; +} + +static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, + struct policy_file *fp) +{ + int nel = 0; + size_t items; + uint32_t buf[1]; + role_trans_rule_t *tr; + int warned = 0; + int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS; + + for (tr = t; tr; tr = tr->next) + if (new_role || only_process(&tr->classes, p)) + nel++; + + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (tr = t; tr; tr = tr->next) { + if (!new_role && !only_process(&tr->classes, p)) { + if (!warned) + WARN(fp->handle, "Discarding role_transition " + "rules for security classes other than " + "\"process\""); + warned = 1; + continue; + } + if (role_set_write(&tr->roles, fp)) + return POLICYDB_ERROR; + if (type_set_write(&tr->types, fp)) + return POLICYDB_ERROR; + if (new_role) + if (ebitmap_write(&tr->classes, fp)) + return POLICYDB_ERROR; + buf[0] = cpu_to_le32(tr->new_role); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; +} + +static int role_allow_rule_write(role_allow_rule_t * r, struct policy_file *fp) +{ + int nel = 0; + size_t items; + uint32_t buf[1]; + role_allow_rule_t *ra; + + for (ra = r; ra; ra = ra->next) + nel++; + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (ra = r; ra; ra = ra->next) { + if (role_set_write(&ra->roles, fp)) + return POLICYDB_ERROR; + if (role_set_write(&ra->new_roles, fp)) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; +} + +static int filename_trans_rule_write(policydb_t *p, filename_trans_rule_t *t, + struct policy_file *fp) +{ + int nel = 0; + size_t items, entries; + uint32_t buf[3], len; + filename_trans_rule_t *ftr; + + for (ftr = t; ftr; ftr = ftr->next) + nel++; + + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + for (ftr = t; ftr; ftr = ftr->next) { + len = strlen(ftr->name); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + items = put_entry(ftr->name, sizeof(char), len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (type_set_write(&ftr->stypes, fp)) + return POLICYDB_ERROR; + if (type_set_write(&ftr->ttypes, fp)) + return POLICYDB_ERROR; + + buf[0] = cpu_to_le32(ftr->tclass); + buf[1] = cpu_to_le32(ftr->otype); + buf[2] = cpu_to_le32(ftr->flags); + + if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS) { + entries = 3; + } else if (!(ftr->flags & RULE_SELF)) { + entries = 2; + } else { + ERR(fp->handle, + "Module contains a self rule not supported by the target module policy version"); + return POLICYDB_ERROR; + } + + items = put_entry(buf, sizeof(uint32_t), entries, fp); + if (items != entries) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; +} + +static int range_trans_rule_write(range_trans_rule_t * t, + struct policy_file *fp) +{ + int nel = 0; + size_t items; + uint32_t buf[1]; + range_trans_rule_t *rt; + + for (rt = t; rt; rt = rt->next) + nel++; + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + for (rt = t; rt; rt = rt->next) { + if (type_set_write(&rt->stypes, fp)) + return POLICYDB_ERROR; + if (type_set_write(&rt->ttypes, fp)) + return POLICYDB_ERROR; + if (ebitmap_write(&rt->tclasses, fp)) + return POLICYDB_ERROR; + if (mls_write_semantic_range_helper(&rt->trange, fp)) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; +} + +static int scope_index_write(scope_index_t * scope_index, + unsigned int num_scope_syms, + struct policy_file *fp) +{ + unsigned int i; + uint32_t buf[1]; + for (i = 0; i < num_scope_syms; i++) { + if (ebitmap_write(scope_index->scope + i, fp) == -1) { + return POLICYDB_ERROR; + } + } + buf[0] = cpu_to_le32(scope_index->class_perms_len); + if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { + return POLICYDB_ERROR; + } + for (i = 0; i < scope_index->class_perms_len; i++) { + if (ebitmap_write(scope_index->class_perms_map + i, fp) == -1) { + return POLICYDB_ERROR; + } + } + return POLICYDB_SUCCESS; +} + +static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms, + policydb_t * p, struct policy_file *fp) +{ + struct policy_data pd; + uint32_t buf[2]; + int i; + buf[0] = cpu_to_le32(decl->decl_id); + buf[1] = cpu_to_le32(decl->enabled); + if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) { + return POLICYDB_ERROR; + } + if (cond_write_list(p, decl->cond_list, fp) == -1 || + avrule_write_list(p, decl->avrules, fp) == -1 || + role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 || + role_allow_rule_write(decl->role_allow_rules, fp) == -1) { + return POLICYDB_ERROR; + } + + if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS && + filename_trans_rule_write(p, decl->filename_trans_rules, fp)) + return POLICYDB_ERROR; + + if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS && + range_trans_rule_write(decl->range_tr_rules, fp) == -1) { + return POLICYDB_ERROR; + } + if (scope_index_write(&decl->required, num_scope_syms, fp) == -1 || + scope_index_write(&decl->declared, num_scope_syms, fp) == -1) { + return POLICYDB_ERROR; + } + pd.fp = fp; + pd.p = p; + for (i = 0; i < num_scope_syms; i++) { + buf[0] = cpu_to_le32(decl->symtab[i].nprim); + buf[1] = cpu_to_le32(decl->symtab[i].table->nel); + if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) { + return POLICYDB_ERROR; + } + if (ksu_hashtab_map(decl->symtab[i].table, write_f[i], &pd)) { + return POLICYDB_ERROR; + } + } + return POLICYDB_SUCCESS; +} + +static int avrule_block_write(avrule_block_t * block, int num_scope_syms, + policydb_t * p, struct policy_file *fp) +{ + /* first write a count of the total number of blocks */ + uint32_t buf[1], num_blocks = 0; + avrule_block_t *cur; + for (cur = block; cur != NULL; cur = cur->next) { + num_blocks++; + } + buf[0] = cpu_to_le32(num_blocks); + if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { + return POLICYDB_ERROR; + } + + /* now write each block */ + for (cur = block; cur != NULL; cur = cur->next) { + uint32_t num_decls = 0; + avrule_decl_t *decl; + /* write a count of number of branches */ + for (decl = cur->branch_list; decl != NULL; decl = decl->next) { + num_decls++; + } + buf[0] = cpu_to_le32(num_decls); + if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { + return POLICYDB_ERROR; + } + for (decl = cur->branch_list; decl != NULL; decl = decl->next) { + if (avrule_decl_write(decl, num_scope_syms, p, fp) == + -1) { + return POLICYDB_ERROR; + } + } + } + return POLICYDB_SUCCESS; +} + +static int scope_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr) +{ + scope_datum_t *scope = (scope_datum_t *) datum; + struct policy_data *pd = ptr; + struct policy_file *fp = pd->fp; + uint32_t static_buf[32], *dyn_buf = NULL, *buf; + size_t key_len = strlen(key); + unsigned int items = 2 + scope->decl_ids_len, i; + int rc; + + buf = static_buf; + if (items >= (sizeof(static_buf) / 4)) { + /* too many things required, so dynamically create a + * buffer. this would have been easier with C99's + * dynamic arrays... */ + rc = POLICYDB_ERROR; + dyn_buf = calloc(items, sizeof(*dyn_buf)); + if (!dyn_buf) + goto err; + buf = dyn_buf; + } + buf[0] = cpu_to_le32(key_len); + + rc = POLICYDB_ERROR; + if (put_entry(buf, sizeof(*buf), 1, fp) != 1 || + put_entry(key, 1, key_len, fp) != key_len) + goto err; + buf[0] = cpu_to_le32(scope->scope); + buf[1] = cpu_to_le32(scope->decl_ids_len); + + for (i = 0; i < scope->decl_ids_len; i++) + buf[2 + i] = cpu_to_le32(scope->decl_ids[i]); + + rc = POLICYDB_ERROR; + if (put_entry(buf, sizeof(*buf), items, fp) != items) + goto err; + rc = POLICYDB_SUCCESS; +err: + free(dyn_buf); + return rc; +} + +static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)), + hashtab_datum_t datum, void *args) +{ + type_datum_t *typdatum = datum; + uint32_t *p_nel = args; + + if (typdatum->flavor == TYPE_ATTRIB) { + /* uncount attribute from total number of types */ + (*p_nel)--; + } + return 0; +} + +static int role_attr_uncount(hashtab_key_t key __attribute__ ((unused)), + hashtab_datum_t datum, void *args) +{ + role_datum_t *role = datum; + uint32_t *p_nel = args; + + if (role->flavor == ROLE_ATTRIB) { + /* uncount attribute from total number of roles */ + (*p_nel)--; + } + return 0; +} + +/* + * Write the configuration data in a policy database + * structure to a policy database binary representation + * file. + */ +int ksu_policydb_write(policydb_t * p, struct policy_file *fp) +{ + unsigned int i, num_syms; + uint32_t buf[32], config; + size_t items, items2, len; + const struct policydb_compat_info *info; + struct policy_data pd; + const char *policydb_str; + + if (p->unsupported_format) + return POLICYDB_UNSUPPORTED; + + pd.fp = fp; + pd.p = p; + + config = 0; + if (p->mls) { + if ((p->policyvers < POLICYDB_VERSION_MLS && + p->policy_type == POLICY_KERN) || + (p->policyvers < MOD_POLICYDB_VERSION_MLS && + p->policy_type == POLICY_BASE) || + (p->policyvers < MOD_POLICYDB_VERSION_MLS && + p->policy_type == POLICY_MOD)) { + ERR(fp->handle, "policy version %d cannot support MLS", + p->policyvers); + return POLICYDB_ERROR; + } + config |= POLICYDB_CONFIG_MLS; + } + + config |= (POLICYDB_CONFIG_UNKNOWN_MASK & p->handle_unknown); + + /* Write the magic number and string identifiers. */ + items = 0; + if (p->policy_type == POLICY_KERN) { + buf[items++] = cpu_to_le32(POLICYDB_MAGIC); + len = strlen(policydb_target_strings[p->target_platform]); + policydb_str = policydb_target_strings[p->target_platform]; + } else { + buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC); + len = strlen(POLICYDB_MOD_STRING); + policydb_str = POLICYDB_MOD_STRING; + } + buf[items++] = cpu_to_le32(len); + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + items = put_entry(policydb_str, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + /* Write the version, config, and table sizes. */ + items = 0; + info = policydb_lookup_compat(p->policyvers, p->policy_type, + p->target_platform); + if (!info) { + ERR(fp->handle, "compatibility lookup failed for policy " + "version %d", p->policyvers); + return POLICYDB_ERROR; + } + + if (p->policy_type != POLICY_KERN) { + buf[items++] = cpu_to_le32(p->policy_type); + } + buf[items++] = cpu_to_le32(p->policyvers); + buf[items++] = cpu_to_le32(config); + buf[items++] = cpu_to_le32(info->sym_num); + buf[items++] = cpu_to_le32(info->ocon_num); + + items2 = put_entry(buf, sizeof(uint32_t), items, fp); + if (items != items2) + return POLICYDB_ERROR; + + if (p->policy_type == POLICY_MOD) { + /* Write module name and version */ + len = strlen(p->name); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + items = put_entry(p->name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + len = strlen(p->version); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + items = put_entry(p->version, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + } + + if ((p->policyvers >= POLICYDB_VERSION_POLCAP && + p->policy_type == POLICY_KERN) || + (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && + p->policy_type == POLICY_BASE) || + (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && + p->policy_type == POLICY_MOD)) { + if (ebitmap_write(&p->policycaps, fp) == -1) + return POLICYDB_ERROR; + } + + if (p->policyvers < POLICYDB_VERSION_PERMISSIVE && + p->policy_type == POLICY_KERN) { + ebitmap_node_t *tnode; + + ebitmap_for_each_positive_bit(&p->permissive_map, tnode, i) { + WARN(fp->handle, "Warning! Policy version %d cannot " + "support permissive types, but some were defined", + p->policyvers); + break; + } + } + + if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && + p->policy_type == POLICY_KERN) { + if (ebitmap_write(&p->permissive_map, fp) == -1) + return POLICYDB_ERROR; + } + + num_syms = info->sym_num; + for (i = 0; i < num_syms; i++) { + buf[0] = cpu_to_le32(p->symtab[i].nprim); + buf[1] = p->symtab[i].table->nel; + + /* + * A special case when writing type/attribute symbol table. + * The kernel policy version less than 24 does not support + * to load entries of attribute, so we have to re-calculate + * the actual number of types except for attributes. + */ + if (i == SYM_TYPES && + p->policyvers < POLICYDB_VERSION_BOUNDARY && + p->policy_type == POLICY_KERN) { + ksu_hashtab_map(p->symtab[i].table, type_attr_uncount, &buf[1]); + } + + /* + * Another special case when writing role/attribute symbol + * table, role attributes are redundant for policy.X, or + * when the pp's version is not big enough. So deduct + * their numbers from p_roles.table->nel. + */ + if ((i == SYM_ROLES) && + ((p->policy_type == POLICY_KERN) || + (p->policy_type != POLICY_KERN && + p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) + (void)ksu_hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]); + + buf[1] = cpu_to_le32(buf[1]); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + if (ksu_hashtab_map(p->symtab[i].table, write_f[i], &pd)) + return POLICYDB_ERROR; + } + + if (p->policy_type == POLICY_KERN) { + if (avtab_write(p, &p->te_avtab, fp)) + return POLICYDB_ERROR; + if (p->policyvers < POLICYDB_VERSION_BOOL) { + if (p->p_bools.nprim) + WARN(fp->handle, "Discarding " + "booleans and conditional rules"); + } else { + if (cond_write_list(p, p->cond_list, fp)) + return POLICYDB_ERROR; + } + if (role_trans_write(p, fp)) + return POLICYDB_ERROR; + if (role_allow_write(p->role_allow, fp)) + return POLICYDB_ERROR; + if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) { + if (filename_trans_write(p, fp)) + return POLICYDB_ERROR; + } else { + if (p->filename_trans) + WARN(fp->handle, "Discarding filename type transition rules"); + } + } else { + if (avrule_block_write(p->global, num_syms, p, fp) == -1) { + return POLICYDB_ERROR; + } + + for (i = 0; i < num_syms; i++) { + buf[0] = cpu_to_le32(p->scope[i].table->nel); + if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) { + return POLICYDB_ERROR; + } + if (ksu_hashtab_map(p->scope[i].table, scope_write, &pd)) + return POLICYDB_ERROR; + } + } + + if (ocontext_write(info, p, fp) == -1 || genfs_write(p, fp) == -1) { + return POLICYDB_ERROR; + } + + if ((p->policyvers >= POLICYDB_VERSION_MLS + && p->policy_type == POLICY_KERN) + || (p->policyvers >= MOD_POLICYDB_VERSION_MLS + && p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS + && p->policy_type == POLICY_BASE)) { + if (range_write(p, fp)) { + return POLICYDB_ERROR; + } + } + + if (p->policy_type == POLICY_KERN + && p->policyvers >= POLICYDB_VERSION_AVTAB) { + for (i = 0; i < p->p_types.nprim; i++) { + if (ebitmap_write(&p->type_attr_map[i], fp) == -1) + return POLICYDB_ERROR; + } + } + + return POLICYDB_SUCCESS; +} diff --git a/kernel/libsepol/src/write.o b/kernel/libsepol/src/write.o new file mode 100644 index 00000000..d4a1728f Binary files /dev/null and b/kernel/libsepol/src/write.o differ diff --git a/kernel/libsepol/tests/.gitignore b/kernel/libsepol/tests/.gitignore new file mode 100644 index 00000000..c3f60fd2 --- /dev/null +++ b/kernel/libsepol/tests/.gitignore @@ -0,0 +1 @@ +libsepol-tests diff --git a/kernel/libsepol/tests/Makefile b/kernel/libsepol/tests/Makefile new file mode 100644 index 00000000..a72c327d --- /dev/null +++ b/kernel/libsepol/tests/Makefile @@ -0,0 +1,60 @@ +ENV ?= env +M4 ?= m4 +MKDIR ?= mkdir +EXE ?= libsepol-tests + +CFLAGS += -g3 -gdwarf-2 -O0 -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -Wno-unused-parameter -Werror + +# Statically link libsepol on the assumption that we are going to +# be testing internal functions. +LIBSEPOL := ../src/libsepol.a + +# In order to load source policies we need to link in the checkpolicy/checkmodule parser and util code. +# This is less than ideal, but it makes the tests easier to maintain by allowing source policies +# to be loaded directly. +CHECKPOLICY := ../../checkpolicy/ +override CPPFLAGS += -I../include/ -I$(CHECKPOLICY) + +# test program object files +objs := $(patsubst %.c,%.o,$(sort $(wildcard *.c))) +parserobjs := $(CHECKPOLICY)queue.o $(CHECKPOLICY)y.tab.o \ + $(CHECKPOLICY)parse_util.o $(CHECKPOLICY)lex.yy.o \ + $(CHECKPOLICY)policy_define.o $(CHECKPOLICY)module_compiler.o + +# test policy pieces +m4support := $(wildcard policies/support/*.spt) +testsuites := $(wildcard policies/test-*) +policysrc := $(foreach path,$(testsuites),$(wildcard $(path)/*.conf)) +stdpol := $(addsuffix .std,$(policysrc)) +mlspol := $(addsuffix .mls,$(policysrc)) +policies := $(stdpol) $(mlspol) + +all: $(EXE) $(policies) +policies: $(policies) + +$(EXE): $(objs) $(parserobjs) $(LIBSEPOL) + $(CC) $(LDFLAGS) $(objs) $(parserobjs) -lcunit $(LIBSEPOL) -o $@ + +%.conf.std: $(m4support) %.conf + $(M4) $(M4PARAMS) $^ > $@ + +%.conf.mls: $(m4support) %.conf + $(M4) $(M4PARAMS) -D enable_mls $^ > $@ + +clean: + rm -f $(objs) $(EXE) + rm -f $(policies) + rm -f policies/test-downgrade/policy.hi policies/test-downgrade/policy.lo + +# mkdir is run in a clean environment created by env -i to avoid failing under ASan with: +# +# ASan runtime does not come first in initial library list; +# you should either link runtime to your application or manually preload it with LD_PRELOAD +# +# when the source code is built with ASan +test: $(EXE) $(policies) + $(ENV) -i $(MKDIR) -p policies/test-downgrade + ../../checkpolicy/checkpolicy -M policies/test-cond/refpolicy-base.conf -o policies/test-downgrade/policy.hi + ./$(EXE) + +.PHONY: all policies clean test diff --git a/kernel/libsepol/tests/debug.c b/kernel/libsepol/tests/debug.c new file mode 100644 index 00000000..ede39bf0 --- /dev/null +++ b/kernel/libsepol/tests/debug.c @@ -0,0 +1,69 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This includes functions used to debug tests (display bitmaps, conditional expressions, etc */ + +#include "debug.h" + +#include + +void print_ebitmap(ebitmap_t * bitmap, FILE * fp) +{ + uint32_t i; + for (i = 0; i < bitmap->highbit; i++) { + fprintf(fp, "%d", ksu_ebitmap_get_bit(bitmap, i)); + } + fprintf(fp, "\n"); +} + +/* stolen from dispol.c */ +void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) +{ + + cond_expr_t *cur; + for (cur = exp; cur != NULL; cur = cur->next) { + switch (cur->expr_type) { + case COND_BOOL: + fprintf(fp, "%s ", p->p_bool_val_to_name[cur->bool - 1]); + break; + case COND_NOT: + fprintf(fp, "! "); + break; + case COND_OR: + fprintf(fp, "|| "); + break; + case COND_AND: + fprintf(fp, "&& "); + break; + case COND_XOR: + fprintf(fp, "^ "); + break; + case COND_EQ: + fprintf(fp, "== "); + break; + case COND_NEQ: + fprintf(fp, "!= "); + break; + default: + fprintf(fp, "error! (%d)", cur->expr_type); + break; + } + } +} diff --git a/kernel/libsepol/tests/debug.h b/kernel/libsepol/tests/debug.h new file mode 100644 index 00000000..c25ebd45 --- /dev/null +++ b/kernel/libsepol/tests/debug.h @@ -0,0 +1,27 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This includes functions used to debug tests (display bitmaps, conditional expressions, etc */ + +#include +#include + +extern void print_ebitmap(ebitmap_t * bitmap, FILE * fp); +extern void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp); diff --git a/kernel/libsepol/tests/helpers.c b/kernel/libsepol/tests/helpers.c new file mode 100644 index 00000000..cd3d3a54 --- /dev/null +++ b/kernel/libsepol/tests/helpers.c @@ -0,0 +1,81 @@ +/* + * Author: Joshua Brindle + * Chad Sellers + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This has helper functions that are common between tests */ + +#include "helpers.h" +#include "parse_util.h" + +#include +#include + +#include + +#include +#include + +int test_load_policy(policydb_t * p, int policy_type, int mls, const char *test_name, const char *policy_name) +{ + char filename[PATH_MAX]; + + if (mls) { + if (snprintf(filename, PATH_MAX, "policies/%s/%s.mls", test_name, policy_name) < 0) { + return -1; + } + } else { + if (snprintf(filename, PATH_MAX, "policies/%s/%s.std", test_name, policy_name) < 0) { + return -1; + } + } + + if (policydb_init(p)) { + fprintf(stderr, "Out of memory"); + return -1; + } + + p->policy_type = policy_type; + p->mls = mls; + + if (read_source_policy(p, filename, test_name)) { + fprintf(stderr, "failed to read policy %s\n", filename); + ksu_policydb_destroy(p); + return -1; + } + + return 0; +} + +avrule_decl_t *test_find_decl_by_sym(policydb_t * p, int symtab, const char *sym) +{ + scope_datum_t *scope = (scope_datum_t *) hashtab_search(p->scope[symtab].table, sym); + + if (scope == NULL) { + return NULL; + } + if (scope->scope != SCOPE_DECL) { + return NULL; + } + if (scope->decl_ids_len != 1) { + return NULL; + } + + return p->decl_val_to_struct[scope->decl_ids[0] - 1]; +} diff --git a/kernel/libsepol/tests/helpers.h b/kernel/libsepol/tests/helpers.h new file mode 100644 index 00000000..fa84cfab --- /dev/null +++ b/kernel/libsepol/tests/helpers.h @@ -0,0 +1,88 @@ +/* + * Author: Joshua Brindle + * Chad Sellers + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#include +#include +#include + +/* helper functions */ + +/* Override CU_*_FATAL() in order to help static analyzers by really asserting that an assertion holds */ +#ifdef __CHECKER__ + +#include + +#undef CU_ASSERT_FATAL +#define CU_ASSERT_FATAL(value) do { \ + int _value = (value); \ + CU_ASSERT(_value); \ + assert(_value); \ + } while (0) + +#undef CU_FAIL_FATAL +#define CU_FAIL_FATAL(msg) do { \ + CU_FAIL(msg); \ + assert(0); \ + } while (0) + +#undef CU_ASSERT_PTR_NOT_NULL_FATAL +#define CU_ASSERT_PTR_NOT_NULL_FATAL(value) do { \ + const void *_value = (value); \ + CU_ASSERT_PTR_NOT_NULL(_value); \ + assert(_value != NULL); \ + } while (0) + +#endif /* __CHECKER__ */ + + +/* Load a source policy into p. policydb_init will called within this function. + * + * Example: test_load_policy(p, POLICY_BASE, 1, "foo", "base.conf") will load the + * policy "policies/foo/mls/base.conf" into p. + * + * Arguments: + * p policydb_t into which the policy will be read. This should be + * malloc'd but not passed to policydb_init. + * policy_type Type of policy expected - POLICY_BASE or POLICY_MOD. + * mls Boolean value indicating whether an mls policy is expected. + * test_name Name of the test which will be the name of the directory in + * which the policies are stored. + * policy_name Name of the policy in the directory. + * + * Returns: + * 0 success + * -1 error - the policydb will be destroyed but not freed. + */ +extern int test_load_policy(policydb_t * p, int policy_type, int mls, const char *test_name, const char *policy_name); + +/* Find an avrule_decl_t by a unique symbol. If the symbol is declared in more + * than one decl an error is returned. + * + * Returns: + * decl success + * NULL error (including more than one declaration) + */ +extern avrule_decl_t *test_find_decl_by_sym(policydb_t * p, int symtab, const char *sym); + +#endif diff --git a/kernel/libsepol/tests/libsepol-tests.c b/kernel/libsepol/tests/libsepol-tests.c new file mode 100644 index 00000000..dc8fd5ce --- /dev/null +++ b/kernel/libsepol/tests/libsepol-tests.c @@ -0,0 +1,125 @@ +/* + * Author: Karl MacMillan + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-cond.h" +#include "test-linker.h" +#include "test-expander.h" +#include "test-deps.h" +#include "test-downgrade.h" + +#include +#include +#include + +#include +#include +#include +#include + +int mls; + +#define DECLARE_SUITE(name) \ + do { \ + suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \ + if (NULL == suite) { \ + CU_cleanup_registry(); \ + return CU_get_error(); \ + } \ + if (name##_add_tests(suite)) { \ + CU_cleanup_registry(); \ + return CU_get_error(); \ + } \ + } while (0) + +static void usage(char *progname) +{ + printf("usage: %s [options]\n", progname); + printf("options:\n"); + printf("\t-v, --verbose\t\t\tverbose output\n"); + printf("\t-i, --interactive\t\tinteractive console\n"); +} + +static bool do_tests(int interactive, int verbose) +{ + CU_pSuite suite = NULL; + unsigned int num_failures; + + if (CUE_SUCCESS != CU_initialize_registry()) + return CU_get_error(); + + DECLARE_SUITE(cond); + DECLARE_SUITE(linker); + DECLARE_SUITE(expander); + DECLARE_SUITE(deps); + DECLARE_SUITE(downgrade); + + if (verbose) + CU_basic_set_mode(CU_BRM_VERBOSE); + else + CU_basic_set_mode(CU_BRM_NORMAL); + + if (interactive) + CU_console_run_tests(); + else + CU_basic_run_tests(); + num_failures = CU_get_number_of_tests_failed(); + CU_cleanup_registry(); + return CU_get_error() == CUE_SUCCESS && num_failures == 0; + +} + +int main(int argc, char **argv) +{ + int i, verbose = 1, interactive = 0; + + struct option opts[] = { + {"verbose", 0, NULL, 'v'}, + {"interactive", 0, NULL, 'i'}, + {NULL, 0, NULL, 0} + }; + + while ((i = getopt_long(argc, argv, "vi", opts, NULL)) != -1) { + switch (i) { + case 'v': + verbose = 1; + break; + case 'i': + interactive = 1; + break; + case 'h': + default:{ + usage(argv[0]); + exit(1); + } + } + } + + /* first do the non-mls tests */ + mls = 0; + if (!do_tests(interactive, verbose)) + return -1; + + /* then with mls */ + mls = 1; + if (!do_tests(interactive, verbose)) + return -1; + + return 0; +} diff --git a/kernel/libsepol/tests/policies/.gitignore b/kernel/libsepol/tests/policies/.gitignore new file mode 100644 index 00000000..5a547a8a --- /dev/null +++ b/kernel/libsepol/tests/policies/.gitignore @@ -0,0 +1,3 @@ +test-downgrade/ +test-*/*.mls +test-*/*.std diff --git a/kernel/libsepol/tests/policies/support/misc_macros.spt b/kernel/libsepol/tests/policies/support/misc_macros.spt new file mode 100644 index 00000000..5fadd0f4 --- /dev/null +++ b/kernel/libsepol/tests/policies/support/misc_macros.spt @@ -0,0 +1,23 @@ + +######################################## +# +# Helper macros +# + +######################################## +# +# gen_user(username, prefix, role_set, mls_defaultlevel, mls_range, [mcs_categories]) +# +define(`gen_user',`dnl +ifdef(`users_extra',`dnl +ifelse(`$2',,,`user $1 prefix $2;') +',`dnl +user $1 roles { $3 }`'ifdef(`enable_mls', ` level $4 range $5')`'ifdef(`enable_mcs',` level s0 range s0`'ifelse(`$6',,,` - s0:$6')'); +')dnl +') + +######################################## +# +# gen_context(context,mls_sensitivity,[mcs_categories]) +# +define(`gen_context',`$1`'ifdef(`enable_mls',`:$2')`'ifdef(`enable_mcs',`:s0`'ifelse(`$3',,,`:$3')')') dnl diff --git a/kernel/libsepol/tests/policies/test-cond/refpolicy-base.conf b/kernel/libsepol/tests/policies/test-cond/refpolicy-base.conf new file mode 100644 index 00000000..1c1ef9ac --- /dev/null +++ b/kernel/libsepol/tests/policies/test-cond/refpolicy-base.conf @@ -0,0 +1,1940 @@ +class security +class process +class system +class capability +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket +class sem +class msg +class msgq +class shm +class ipc +class passwd # userspace +class drawable # userspace +class window # userspace +class gc # userspace +class font # userspace +class colormap # userspace +class property # userspace +class cursor # userspace +class xclient # userspace +class xinput # userspace +class xserver # userspace +class xextension # userspace +class pax +class netlink_route_socket +class netlink_firewall_socket +class netlink_tcpdiag_socket +class netlink_nflog_socket +class netlink_xfrm_socket +class netlink_selinux_socket +class netlink_audit_socket +class netlink_ip6fw_socket +class netlink_dnrt_socket +class dbus # userspace +class nscd # userspace +class association +class netlink_kobject_uevent_socket +sid kernel +sid security +sid unlabeled +sid fs +sid file +sid file_labels +sid init +sid any_socket +sid port +sid netif +sid netmsg +sid node +sid igmp_packet +sid icmp_socket +sid tcp_socket +sid sysctl_modprobe +sid sysctl +sid sysctl_fs +sid sysctl_kernel +sid sysctl_net +sid sysctl_net_unix +sid sysctl_vm +sid sysctl_dev +sid kmod +sid policy +sid scmp_packet +sid devnull +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} +common socket +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} +class file +inherits file +{ + execute_no_trans + entrypoint + execmod +} +class lnk_file +inherits file +class chr_file +inherits file +{ + execute_no_trans + entrypoint + execmod +} +class blk_file +inherits file +class sock_file +inherits file +class fifo_file +inherits file +class fd +{ + use +} +class socket +inherits socket +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom + node_bind + name_connect +} +class udp_socket +inherits socket +{ + node_bind +} +class rawip_socket +inherits socket +{ + node_bind +} +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} +class netlink_socket +inherits socket +class packet_socket +inherits socket +class key_socket +inherits socket +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} +class unix_dgram_socket +inherits socket +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share + getattr + setexec + setfscreate + noatsecure + siginh + setrlimit + rlimitinh + dyntransition + setcurrent + execmem + execstack + execheap +} +class ipc +inherits ipc +class sem +inherits ipc +class msgq +inherits ipc +{ + enqueue +} +class msg +{ + send + receive +} +class shm +inherits ipc +{ + lock +} +class security +{ + compute_av + compute_create + compute_member + check_context + load_policy + compute_relabel + compute_user + setenforce # was avc_toggle in system class + setbool + setsecparam + setcheckreqprot +} +class system +{ + ipc_info + syslog_read + syslog_mod + syslog_console +} +class capability +{ + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease + audit_write + audit_control +} +class passwd +{ + passwd # change another user passwd + chfn # change another user finger info + chsh # change another user shell + rootok # pam_rootok check (skip auth) + crontab # crontab on another user +} +class drawable +{ + create + destroy + draw + copy + getattr +} +class gc +{ + create + free + getattr + setattr +} +class window +{ + addchild + create + destroy + map + unmap + chstack + chproplist + chprop + listprop + getattr + setattr + setfocus + move + chselection + chparent + ctrllife + enumerate + transparent + mousemotion + clientcomevent + inputevent + drawevent + windowchangeevent + windowchangerequest + serverchangeevent + extensionevent +} +class font +{ + load + free + getattr + use +} +class colormap +{ + create + free + install + uninstall + list + read + store + getattr + setattr +} +class property +{ + create + free + read + write +} +class cursor +{ + create + createglyph + free + assign + setattr +} +class xclient +{ + kill +} +class xinput +{ + lookup + getattr + setattr + setfocus + warppointer + activegrab + passivegrab + ungrab + bell + mousemotion + relabelinput +} +class xserver +{ + screensaver + gethostlist + sethostlist + getfontpath + setfontpath + getattr + grab + ungrab +} +class xextension +{ + query + use +} +class pax +{ + pageexec # Paging based non-executable pages + emutramp # Emulate trampolines + mprotect # Restrict mprotect() + randmmap # Randomize mmap() base + randexec # Randomize ET_EXEC base + segmexec # Segmentation based non-executable pages +} +class netlink_route_socket +inherits socket +{ + nlmsg_read + nlmsg_write +} +class netlink_firewall_socket +inherits socket +{ + nlmsg_read + nlmsg_write +} +class netlink_tcpdiag_socket +inherits socket +{ + nlmsg_read + nlmsg_write +} +class netlink_nflog_socket +inherits socket +class netlink_xfrm_socket +inherits socket +{ + nlmsg_read + nlmsg_write +} +class netlink_selinux_socket +inherits socket +class netlink_audit_socket +inherits socket +{ + nlmsg_read + nlmsg_write + nlmsg_relay + nlmsg_readpriv +} +class netlink_ip6fw_socket +inherits socket +{ + nlmsg_read + nlmsg_write +} +class netlink_dnrt_socket +inherits socket +class dbus +{ + acquire_svc + send_msg +} +class nscd +{ + getpwd + getgrp + gethost + getstat + admin + shmempwd + shmemgrp + shmemhost +} +class association +{ + sendto + recvfrom + setcontext +} +class netlink_kobject_uevent_socket +inherits socket +sensitivity s0; +dominance { s0 } +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; +category c24; category c25; category c26; category c27; +category c28; category c29; category c30; category c31; +category c32; category c33; category c34; category c35; +category c36; category c37; category c38; category c39; +category c40; category c41; category c42; category c43; +category c44; category c45; category c46; category c47; +category c48; category c49; category c50; category c51; +category c52; category c53; category c54; category c55; +category c56; category c57; category c58; category c59; +category c60; category c61; category c62; category c63; +category c64; category c65; category c66; category c67; +category c68; category c69; category c70; category c71; +category c72; category c73; category c74; category c75; +category c76; category c77; category c78; category c79; +category c80; category c81; category c82; category c83; +category c84; category c85; category c86; category c87; +category c88; category c89; category c90; category c91; +category c92; category c93; category c94; category c95; +category c96; category c97; category c98; category c99; +category c100; category c101; category c102; category c103; +category c104; category c105; category c106; category c107; +category c108; category c109; category c110; category c111; +category c112; category c113; category c114; category c115; +category c116; category c117; category c118; category c119; +category c120; category c121; category c122; category c123; +category c124; category c125; category c126; category c127; +category c128; category c129; category c130; category c131; +category c132; category c133; category c134; category c135; +category c136; category c137; category c138; category c139; +category c140; category c141; category c142; category c143; +category c144; category c145; category c146; category c147; +category c148; category c149; category c150; category c151; +category c152; category c153; category c154; category c155; +category c156; category c157; category c158; category c159; +category c160; category c161; category c162; category c163; +category c164; category c165; category c166; category c167; +category c168; category c169; category c170; category c171; +category c172; category c173; category c174; category c175; +category c176; category c177; category c178; category c179; +category c180; category c181; category c182; category c183; +category c184; category c185; category c186; category c187; +category c188; category c189; category c190; category c191; +category c192; category c193; category c194; category c195; +category c196; category c197; category c198; category c199; +category c200; category c201; category c202; category c203; +category c204; category c205; category c206; category c207; +category c208; category c209; category c210; category c211; +category c212; category c213; category c214; category c215; +category c216; category c217; category c218; category c219; +category c220; category c221; category c222; category c223; +category c224; category c225; category c226; category c227; +category c228; category c229; category c230; category c231; +category c232; category c233; category c234; category c235; +category c236; category c237; category c238; category c239; +category c240; category c241; category c242; category c243; +category c244; category c245; category c246; category c247; +category c248; category c249; category c250; category c251; +category c252; category c253; category c254; category c255; +level s0:c0.c255; +mlsconstrain file { write setattr append unlink link rename + ioctl lock execute relabelfrom } (h1 dom h2); +mlsconstrain file { create relabelto } ((h1 dom h2) and (l2 eq h2)); +mlsconstrain file { read } ((h1 dom h2) or ( t2 == domain ) or ( t1 == mlsfileread )); +mlsconstrain { dir lnk_file chr_file blk_file sock_file fifo_file } { relabelfrom } + ( h1 dom h2 ); +mlsconstrain { dir lnk_file chr_file blk_file sock_file fifo_file } { create relabelto } + (( h1 dom h2 ) and ( l2 eq h2 )); +mlsconstrain process { ptrace } ( h1 dom h2 ); +mlsconstrain process { sigkill sigstop } ( h1 dom h2 ) or + ( t1 == mcskillall ); +mlsconstrain xextension query ( t1 == mlsfileread ); +attribute netif_type; +attribute node_type; +attribute port_type; +attribute reserved_port_type; +attribute device_node; +attribute memory_raw_read; +attribute memory_raw_write; +attribute domain; +attribute unconfined_domain_type; +attribute set_curr_context; +attribute entry_type; +attribute privfd; +attribute can_change_process_identity; +attribute can_change_process_role; +attribute can_change_object_identity; +attribute can_system_change; +attribute process_user_target; +attribute cron_source_domain; +attribute cron_job_domain; +attribute process_uncond_exempt; # add userhelperdomain to this one +attribute file_type; +attribute lockfile; +attribute mountpoint; +attribute pidfile; +attribute polydir; +attribute usercanread; +attribute polyparent; +attribute polymember; +attribute security_file_type; +attribute tmpfile; +attribute tmpfsfile; +attribute filesystem_type; +attribute noxattrfs; +attribute can_load_kernmodule; +attribute can_receive_kernel_messages; +attribute kern_unconfined; +attribute proc_type; +attribute sysctl_type; +attribute mcskillall; +attribute mlsfileread; +attribute mlsfilereadtoclr; +attribute mlsfilewrite; +attribute mlsfilewritetoclr; +attribute mlsfileupgrade; +attribute mlsfiledowngrade; +attribute mlsnetread; +attribute mlsnetreadtoclr; +attribute mlsnetwrite; +attribute mlsnetwritetoclr; +attribute mlsnetupgrade; +attribute mlsnetdowngrade; +attribute mlsnetrecvall; +attribute mlsipcread; +attribute mlsipcreadtoclr; +attribute mlsipcwrite; +attribute mlsipcwritetoclr; +attribute mlsprocread; +attribute mlsprocreadtoclr; +attribute mlsprocwrite; +attribute mlsprocwritetoclr; +attribute mlsprocsetsl; +attribute mlsxwinread; +attribute mlsxwinreadtoclr; +attribute mlsxwinwrite; +attribute mlsxwinwritetoclr; +attribute mlsxwinreadproperty; +attribute mlsxwinwriteproperty; +attribute mlsxwinreadcolormap; +attribute mlsxwinwritecolormap; +attribute mlsxwinwritexinput; +attribute mlstrustedobject; +attribute privrangetrans; +attribute mlsrangetrans; +attribute can_load_policy; +attribute can_setenforce; +attribute can_setsecparam; +attribute ttynode; +attribute ptynode; +attribute server_ptynode; +attribute serial_device; +type bin_t; +type sbin_t; +type ls_exec_t; +type shell_exec_t; +type chroot_exec_t; +type ppp_device_t; +type tun_tap_device_t; +type port_t, port_type; +type reserved_port_t, port_type, reserved_port_type; +type afs_bos_port_t, port_type; +type afs_fs_port_t, port_type; +type afs_ka_port_t, port_type; +type afs_pt_port_t, port_type; +type afs_vl_port_t, port_type; +type amanda_port_t, port_type; +type amavisd_recv_port_t, port_type; +type amavisd_send_port_t, port_type; +type asterisk_port_t, port_type; +type auth_port_t, port_type; +type bgp_port_t, port_type; +type biff_port_t, port_type, reserved_port_type; +type clamd_port_t, port_type; +type clockspeed_port_t, port_type; +type comsat_port_t, port_type; +type cvs_port_t, port_type; +type dcc_port_t, port_type; +type dbskkd_port_t, port_type; +type dhcpc_port_t, port_type; +type dhcpd_port_t, port_type; +type dict_port_t, port_type; +type distccd_port_t, port_type; +type dns_port_t, port_type; +type fingerd_port_t, port_type; +type ftp_data_port_t, port_type; +type ftp_port_t, port_type; +type gatekeeper_port_t, port_type; +type giftd_port_t, port_type; +type gopher_port_t, port_type; +type http_cache_port_t, port_type; +type http_port_t, port_type; +type howl_port_t, port_type; +type hplip_port_t, port_type; +type i18n_input_port_t, port_type; +type imaze_port_t, port_type; +type inetd_child_port_t, port_type; +type innd_port_t, port_type; +type ipp_port_t, port_type; +type ircd_port_t, port_type; +type isakmp_port_t, port_type; +type jabber_client_port_t, port_type; +type jabber_interserver_port_t, port_type; +type kerberos_admin_port_t, port_type; +type kerberos_master_port_t, port_type; +type kerberos_port_t, port_type; +type ktalkd_port_t, port_type; +type ldap_port_t, port_type; +type lrrd_port_t, port_type; +type mail_port_t, port_type; +type monopd_port_t, port_type; +type mysqld_port_t, port_type; +type nessus_port_t, port_type; +type nmbd_port_t, port_type; +type ntp_port_t, port_type; +type openvpn_port_t, port_type; +type pegasus_http_port_t, port_type; +type pegasus_https_port_t, port_type; +type pop_port_t, port_type; +type portmap_port_t, port_type; +type postgresql_port_t, port_type; +type postgrey_port_t, port_type; +type printer_port_t, port_type; +type ptal_port_t, port_type; +type pxe_port_t, port_type; +type pyzor_port_t, port_type; +type radacct_port_t, port_type; +type radius_port_t, port_type; +type razor_port_t, port_type; +type rlogind_port_t, port_type; +type rndc_port_t, port_type; +type router_port_t, port_type; +type rsh_port_t, port_type; +type rsync_port_t, port_type; +type smbd_port_t, port_type; +type smtp_port_t, port_type; +type snmp_port_t, port_type; +type spamd_port_t, port_type; +type ssh_port_t, port_type; +type soundd_port_t, port_type; +type socks_port_t, port_type; type stunnel_port_t, port_type; +type swat_port_t, port_type; +type syslogd_port_t, port_type; +type telnetd_port_t, port_type; +type tftp_port_t, port_type; +type transproxy_port_t, port_type; +type utcpserver_port_t, port_type; +type uucpd_port_t, port_type; +type vnc_port_t, port_type; +type xserver_port_t, port_type; +type xen_port_t, port_type; +type zebra_port_t, port_type; +type zope_port_t, port_type; +type node_t, node_type; +type compat_ipv4_node_t alias node_compat_ipv4_t, node_type; +type inaddr_any_node_t alias node_inaddr_any_t, node_type; +type node_internal_t, node_type; +type link_local_node_t alias node_link_local_t, node_type; +type lo_node_t alias node_lo_t, node_type; +type mapped_ipv4_node_t alias node_mapped_ipv4_t, node_type; +type multicast_node_t alias node_multicast_t, node_type; +type site_local_node_t alias node_site_local_t, node_type; +type unspec_node_t alias node_unspec_t, node_type; +type netif_t, netif_type; +type device_t; +type agp_device_t; +type apm_bios_t; +type cardmgr_dev_t; +type clock_device_t; +type cpu_device_t; +type crypt_device_t; +type dri_device_t; +type event_device_t; +type framebuf_device_t; +type lvm_control_t; +type memory_device_t; +type misc_device_t; +type mouse_device_t; +type mtrr_device_t; +type null_device_t; +type power_device_t; +type printer_device_t; +type random_device_t; +type scanner_device_t; +type sound_device_t; +type sysfs_t; +type urandom_device_t; +type usbfs_t alias usbdevfs_t; +type usb_device_t; +type v4l_device_t; +type xserver_misc_device_t; +type zero_device_t; +type xconsole_device_t; +type devfs_control_t; +type boot_t; +type default_t, file_type, mountpoint; +type etc_t, file_type; +type etc_runtime_t, file_type; +type file_t, file_type, mountpoint; +type home_root_t, file_type, mountpoint; +type lost_found_t, file_type; +type mnt_t, file_type, mountpoint; +type modules_object_t; +type no_access_t, file_type; +type poly_t, file_type; +type readable_t, file_type; +type root_t, file_type, mountpoint; +type src_t, file_type, mountpoint; +type system_map_t; +type tmp_t, mountpoint; #, polydir +type usr_t, file_type, mountpoint; +type var_t, file_type, mountpoint; +type var_lib_t, file_type, mountpoint; +type var_lock_t, file_type, lockfile; +type var_run_t, file_type, pidfile; +type var_spool_t; +type fs_t; +type bdev_t; +type binfmt_misc_fs_t; +type capifs_t; +type configfs_t; +type eventpollfs_t; +type futexfs_t; +type hugetlbfs_t; +type inotifyfs_t; +type nfsd_fs_t; +type ramfs_t; +type romfs_t; +type rpc_pipefs_t; +type tmpfs_t; +type autofs_t, noxattrfs; +type cifs_t alias sambafs_t, noxattrfs; +type dosfs_t, noxattrfs; +type iso9660_t, filesystem_type, noxattrfs; +type removable_t, noxattrfs; +type nfs_t, filesystem_type, noxattrfs; +type kernel_t, can_load_kernmodule; +type debugfs_t; +type proc_t, proc_type; +type proc_kmsg_t, proc_type; +type proc_kcore_t, proc_type; +type proc_mdstat_t, proc_type; +type proc_net_t, proc_type; +type proc_xen_t, proc_type; +type sysctl_t, sysctl_type; +type sysctl_irq_t, sysctl_type; +type sysctl_rpc_t, sysctl_type; +type sysctl_fs_t, sysctl_type; +type sysctl_kernel_t, sysctl_type; +type sysctl_modprobe_t, sysctl_type; +type sysctl_hotplug_t, sysctl_type; +type sysctl_net_t, sysctl_type; +type sysctl_net_unix_t, sysctl_type; +type sysctl_vm_t, sysctl_type; +type sysctl_dev_t, sysctl_type; +type unlabeled_t; +type auditd_exec_t; +type crond_exec_t; +type cupsd_exec_t; +type getty_t; +type init_t; +type init_exec_t; +type initrc_t; +type initrc_exec_t; +type login_exec_t; +type sshd_exec_t; +type su_exec_t; +type udev_exec_t; +type unconfined_t; +type xdm_exec_t; +type lvm_exec_t; +type security_t; +type bsdpty_device_t; +type console_device_t; +type devpts_t; +type devtty_t; +type ptmx_t; +type tty_device_t, serial_device; +type usbtty_device_t, serial_device; + bool secure_mode false; + bool secure_mode_insmod false; + bool secure_mode_policyload false; + bool allow_cvs_read_shadow false; + bool allow_execheap false; + bool allow_execmem true; + bool allow_execmod false; + bool allow_execstack true; + bool allow_ftpd_anon_write false; + bool allow_gssd_read_tmp true; + bool allow_httpd_anon_write false; + bool allow_java_execstack false; + bool allow_kerberos true; + bool allow_rsync_anon_write false; + bool allow_saslauthd_read_shadow false; + bool allow_smbd_anon_write false; + bool allow_ptrace false; + bool allow_ypbind false; + bool fcron_crond false; + bool ftp_home_dir false; + bool ftpd_is_daemon true; + bool httpd_builtin_scripting true; + bool httpd_can_network_connect false; + bool httpd_can_network_connect_db false; + bool httpd_can_network_relay false; + bool httpd_enable_cgi true; + bool httpd_enable_ftp_server false; + bool httpd_enable_homedirs true; + bool httpd_ssi_exec true; + bool httpd_tty_comm false; + bool httpd_unified true; + bool named_write_master_zones false; + bool nfs_export_all_rw true; + bool nfs_export_all_ro true; + bool pppd_can_insmod false; + bool read_default_t true; + bool run_ssh_inetd false; + bool samba_enable_home_dirs false; + bool spamassasin_can_network false; + bool squid_connect_any false; + bool ssh_sysadm_login false; + bool stunnel_is_daemon false; + bool use_nfs_home_dirs false; + bool use_samba_home_dirs false; + bool user_ping true; + bool spamd_enable_home_dirs true; + allow bin_t fs_t:filesystem associate; + allow bin_t noxattrfs:filesystem associate; + typeattribute bin_t file_type; + allow sbin_t fs_t:filesystem associate; + allow sbin_t noxattrfs:filesystem associate; + typeattribute sbin_t file_type; + allow ls_exec_t fs_t:filesystem associate; + allow ls_exec_t noxattrfs:filesystem associate; + typeattribute ls_exec_t file_type; +typeattribute ls_exec_t entry_type; + allow shell_exec_t fs_t:filesystem associate; + allow shell_exec_t noxattrfs:filesystem associate; + typeattribute shell_exec_t file_type; + allow chroot_exec_t fs_t:filesystem associate; + allow chroot_exec_t noxattrfs:filesystem associate; + typeattribute chroot_exec_t file_type; + typeattribute ppp_device_t device_node; + allow ppp_device_t fs_t:filesystem associate; + allow ppp_device_t tmpfs_t:filesystem associate; + allow ppp_device_t tmp_t:filesystem associate; + typeattribute tun_tap_device_t device_node; + allow tun_tap_device_t fs_t:filesystem associate; + allow tun_tap_device_t tmpfs_t:filesystem associate; + allow tun_tap_device_t tmp_t:filesystem associate; +typeattribute auth_port_t reserved_port_type; +typeattribute bgp_port_t reserved_port_type; +typeattribute bgp_port_t reserved_port_type; +typeattribute comsat_port_t reserved_port_type; +typeattribute dhcpc_port_t reserved_port_type; +typeattribute dhcpd_port_t reserved_port_type; +typeattribute dhcpd_port_t reserved_port_type; +typeattribute dhcpd_port_t reserved_port_type; +typeattribute dhcpd_port_t reserved_port_type; +typeattribute dhcpd_port_t reserved_port_type; +typeattribute dns_port_t reserved_port_type; +typeattribute dns_port_t reserved_port_type; +typeattribute fingerd_port_t reserved_port_type; +typeattribute ftp_data_port_t reserved_port_type; +typeattribute ftp_port_t reserved_port_type; +typeattribute gopher_port_t reserved_port_type; +typeattribute gopher_port_t reserved_port_type; +typeattribute http_port_t reserved_port_type; +typeattribute http_port_t reserved_port_type; +typeattribute http_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute inetd_child_port_t reserved_port_type; +typeattribute innd_port_t reserved_port_type; +typeattribute ipp_port_t reserved_port_type; +typeattribute ipp_port_t reserved_port_type; +typeattribute isakmp_port_t reserved_port_type; +typeattribute kerberos_admin_port_t reserved_port_type; +typeattribute kerberos_admin_port_t reserved_port_type; +typeattribute kerberos_admin_port_t reserved_port_type; +typeattribute kerberos_port_t reserved_port_type; +typeattribute kerberos_port_t reserved_port_type; +typeattribute kerberos_port_t reserved_port_type; +typeattribute kerberos_port_t reserved_port_type; +typeattribute ktalkd_port_t reserved_port_type; +typeattribute ktalkd_port_t reserved_port_type; +typeattribute ldap_port_t reserved_port_type; +typeattribute ldap_port_t reserved_port_type; +typeattribute ldap_port_t reserved_port_type; +typeattribute ldap_port_t reserved_port_type; +typeattribute nmbd_port_t reserved_port_type; +typeattribute nmbd_port_t reserved_port_type; +typeattribute nmbd_port_t reserved_port_type; +typeattribute ntp_port_t reserved_port_type; +typeattribute pop_port_t reserved_port_type; +typeattribute pop_port_t reserved_port_type; +typeattribute pop_port_t reserved_port_type; +typeattribute pop_port_t reserved_port_type; +typeattribute pop_port_t reserved_port_type; +typeattribute pop_port_t reserved_port_type; +typeattribute pop_port_t reserved_port_type; +typeattribute portmap_port_t reserved_port_type; +typeattribute portmap_port_t reserved_port_type; +typeattribute printer_port_t reserved_port_type; +typeattribute rlogind_port_t reserved_port_type; +typeattribute rndc_port_t reserved_port_type; +typeattribute router_port_t reserved_port_type; +typeattribute rsh_port_t reserved_port_type; +typeattribute rsync_port_t reserved_port_type; +typeattribute rsync_port_t reserved_port_type; +typeattribute smbd_port_t reserved_port_type; +typeattribute smbd_port_t reserved_port_type; +typeattribute smtp_port_t reserved_port_type; +typeattribute smtp_port_t reserved_port_type; +typeattribute smtp_port_t reserved_port_type; +typeattribute snmp_port_t reserved_port_type; +typeattribute snmp_port_t reserved_port_type; +typeattribute snmp_port_t reserved_port_type; +typeattribute spamd_port_t reserved_port_type; +typeattribute ssh_port_t reserved_port_type; +typeattribute swat_port_t reserved_port_type; +typeattribute syslogd_port_t reserved_port_type; +typeattribute telnetd_port_t reserved_port_type; +typeattribute tftp_port_t reserved_port_type; +typeattribute uucpd_port_t reserved_port_type; + allow device_t tmpfs_t:filesystem associate; + allow device_t fs_t:filesystem associate; + allow device_t noxattrfs:filesystem associate; + typeattribute device_t file_type; + allow device_t fs_t:filesystem associate; + allow device_t noxattrfs:filesystem associate; + typeattribute device_t file_type; + typeattribute device_t mountpoint; + allow device_t tmp_t:filesystem associate; + typeattribute agp_device_t device_node; + allow agp_device_t fs_t:filesystem associate; + allow agp_device_t tmpfs_t:filesystem associate; + allow agp_device_t tmp_t:filesystem associate; + typeattribute apm_bios_t device_node; + allow apm_bios_t fs_t:filesystem associate; + allow apm_bios_t tmpfs_t:filesystem associate; + allow apm_bios_t tmp_t:filesystem associate; + typeattribute cardmgr_dev_t device_node; + allow cardmgr_dev_t fs_t:filesystem associate; + allow cardmgr_dev_t tmpfs_t:filesystem associate; + allow cardmgr_dev_t tmp_t:filesystem associate; + allow cardmgr_dev_t fs_t:filesystem associate; + allow cardmgr_dev_t noxattrfs:filesystem associate; + typeattribute cardmgr_dev_t file_type; + allow cardmgr_dev_t fs_t:filesystem associate; + allow cardmgr_dev_t noxattrfs:filesystem associate; + typeattribute cardmgr_dev_t file_type; + typeattribute cardmgr_dev_t polymember; + allow cardmgr_dev_t tmpfs_t:filesystem associate; + typeattribute cardmgr_dev_t tmpfile; + allow cardmgr_dev_t tmp_t:filesystem associate; + typeattribute clock_device_t device_node; + allow clock_device_t fs_t:filesystem associate; + allow clock_device_t tmpfs_t:filesystem associate; + allow clock_device_t tmp_t:filesystem associate; + typeattribute cpu_device_t device_node; + allow cpu_device_t fs_t:filesystem associate; + allow cpu_device_t tmpfs_t:filesystem associate; + allow cpu_device_t tmp_t:filesystem associate; + typeattribute crypt_device_t device_node; + allow crypt_device_t fs_t:filesystem associate; + allow crypt_device_t tmpfs_t:filesystem associate; + allow crypt_device_t tmp_t:filesystem associate; + typeattribute dri_device_t device_node; + allow dri_device_t fs_t:filesystem associate; + allow dri_device_t tmpfs_t:filesystem associate; + allow dri_device_t tmp_t:filesystem associate; + typeattribute event_device_t device_node; + allow event_device_t fs_t:filesystem associate; + allow event_device_t tmpfs_t:filesystem associate; + allow event_device_t tmp_t:filesystem associate; + typeattribute framebuf_device_t device_node; + allow framebuf_device_t fs_t:filesystem associate; + allow framebuf_device_t tmpfs_t:filesystem associate; + allow framebuf_device_t tmp_t:filesystem associate; + typeattribute lvm_control_t device_node; + allow lvm_control_t fs_t:filesystem associate; + allow lvm_control_t tmpfs_t:filesystem associate; + allow lvm_control_t tmp_t:filesystem associate; + typeattribute memory_device_t device_node; + allow memory_device_t fs_t:filesystem associate; + allow memory_device_t tmpfs_t:filesystem associate; + allow memory_device_t tmp_t:filesystem associate; +neverallow ~memory_raw_read memory_device_t:{ chr_file blk_file } read; +neverallow ~memory_raw_write memory_device_t:{ chr_file blk_file } { append write }; + typeattribute misc_device_t device_node; + allow misc_device_t fs_t:filesystem associate; + allow misc_device_t tmpfs_t:filesystem associate; + allow misc_device_t tmp_t:filesystem associate; + typeattribute mouse_device_t device_node; + allow mouse_device_t fs_t:filesystem associate; + allow mouse_device_t tmpfs_t:filesystem associate; + allow mouse_device_t tmp_t:filesystem associate; + typeattribute mtrr_device_t device_node; + allow mtrr_device_t fs_t:filesystem associate; + allow mtrr_device_t tmpfs_t:filesystem associate; + allow mtrr_device_t tmp_t:filesystem associate; + typeattribute null_device_t device_node; + allow null_device_t fs_t:filesystem associate; + allow null_device_t tmpfs_t:filesystem associate; + allow null_device_t tmp_t:filesystem associate; + typeattribute null_device_t mlstrustedobject; + typeattribute power_device_t device_node; + allow power_device_t fs_t:filesystem associate; + allow power_device_t tmpfs_t:filesystem associate; + allow power_device_t tmp_t:filesystem associate; + typeattribute printer_device_t device_node; + allow printer_device_t fs_t:filesystem associate; + allow printer_device_t tmpfs_t:filesystem associate; + allow printer_device_t tmp_t:filesystem associate; + typeattribute random_device_t device_node; + allow random_device_t fs_t:filesystem associate; + allow random_device_t tmpfs_t:filesystem associate; + allow random_device_t tmp_t:filesystem associate; + typeattribute scanner_device_t device_node; + allow scanner_device_t fs_t:filesystem associate; + allow scanner_device_t tmpfs_t:filesystem associate; + allow scanner_device_t tmp_t:filesystem associate; + typeattribute sound_device_t device_node; + allow sound_device_t fs_t:filesystem associate; + allow sound_device_t tmpfs_t:filesystem associate; + allow sound_device_t tmp_t:filesystem associate; + allow sysfs_t fs_t:filesystem associate; + allow sysfs_t noxattrfs:filesystem associate; + typeattribute sysfs_t file_type; + typeattribute sysfs_t mountpoint; + typeattribute sysfs_t filesystem_type; + allow sysfs_t self:filesystem associate; + typeattribute urandom_device_t device_node; + allow urandom_device_t fs_t:filesystem associate; + allow urandom_device_t tmpfs_t:filesystem associate; + allow urandom_device_t tmp_t:filesystem associate; + allow usbfs_t fs_t:filesystem associate; + allow usbfs_t noxattrfs:filesystem associate; + typeattribute usbfs_t file_type; + typeattribute usbfs_t mountpoint; + typeattribute usbfs_t filesystem_type; + allow usbfs_t self:filesystem associate; + typeattribute usbfs_t noxattrfs; + typeattribute usb_device_t device_node; + allow usb_device_t fs_t:filesystem associate; + allow usb_device_t tmpfs_t:filesystem associate; + allow usb_device_t tmp_t:filesystem associate; + typeattribute v4l_device_t device_node; + allow v4l_device_t fs_t:filesystem associate; + allow v4l_device_t tmpfs_t:filesystem associate; + allow v4l_device_t tmp_t:filesystem associate; + typeattribute xserver_misc_device_t device_node; + allow xserver_misc_device_t fs_t:filesystem associate; + allow xserver_misc_device_t tmpfs_t:filesystem associate; + allow xserver_misc_device_t tmp_t:filesystem associate; + typeattribute zero_device_t device_node; + allow zero_device_t fs_t:filesystem associate; + allow zero_device_t tmpfs_t:filesystem associate; + allow zero_device_t tmp_t:filesystem associate; + typeattribute zero_device_t mlstrustedobject; + allow xconsole_device_t fs_t:filesystem associate; + allow xconsole_device_t noxattrfs:filesystem associate; + typeattribute xconsole_device_t file_type; + allow xconsole_device_t tmpfs_t:filesystem associate; + allow xconsole_device_t tmp_t:filesystem associate; + typeattribute devfs_control_t device_node; + allow devfs_control_t fs_t:filesystem associate; + allow devfs_control_t tmpfs_t:filesystem associate; + allow devfs_control_t tmp_t:filesystem associate; +neverallow domain ~domain:process { transition dyntransition }; +neverallow { domain -set_curr_context } self:process setcurrent; +neverallow { domain unlabeled_t } ~{ domain unlabeled_t }:process *; +neverallow ~{ domain unlabeled_t } *:process *; +allow file_type self:filesystem associate; + allow boot_t fs_t:filesystem associate; + allow boot_t noxattrfs:filesystem associate; + typeattribute boot_t file_type; + allow boot_t fs_t:filesystem associate; + allow boot_t noxattrfs:filesystem associate; + typeattribute boot_t file_type; + typeattribute boot_t mountpoint; + allow default_t fs_t:filesystem associate; + allow default_t noxattrfs:filesystem associate; + allow etc_t fs_t:filesystem associate; + allow etc_t noxattrfs:filesystem associate; + allow etc_runtime_t fs_t:filesystem associate; + allow etc_runtime_t noxattrfs:filesystem associate; + allow file_t fs_t:filesystem associate; + allow file_t noxattrfs:filesystem associate; + allow kernel_t file_t:dir mounton; + allow home_root_t fs_t:filesystem associate; + allow home_root_t noxattrfs:filesystem associate; + allow home_root_t fs_t:filesystem associate; + allow home_root_t noxattrfs:filesystem associate; + typeattribute home_root_t file_type; + typeattribute home_root_t polyparent; + allow lost_found_t fs_t:filesystem associate; + allow lost_found_t noxattrfs:filesystem associate; + allow mnt_t fs_t:filesystem associate; + allow mnt_t noxattrfs:filesystem associate; + allow modules_object_t fs_t:filesystem associate; + allow modules_object_t noxattrfs:filesystem associate; + typeattribute modules_object_t file_type; + allow no_access_t fs_t:filesystem associate; + allow no_access_t noxattrfs:filesystem associate; + allow poly_t fs_t:filesystem associate; + allow poly_t noxattrfs:filesystem associate; + allow readable_t fs_t:filesystem associate; + allow readable_t noxattrfs:filesystem associate; + allow root_t fs_t:filesystem associate; + allow root_t noxattrfs:filesystem associate; + allow root_t fs_t:filesystem associate; + allow root_t noxattrfs:filesystem associate; + typeattribute root_t file_type; + typeattribute root_t polyparent; + allow kernel_t root_t:dir mounton; + allow src_t fs_t:filesystem associate; + allow src_t noxattrfs:filesystem associate; + allow system_map_t fs_t:filesystem associate; + allow system_map_t noxattrfs:filesystem associate; + typeattribute system_map_t file_type; + allow tmp_t fs_t:filesystem associate; + allow tmp_t noxattrfs:filesystem associate; + typeattribute tmp_t file_type; + allow tmp_t fs_t:filesystem associate; + allow tmp_t noxattrfs:filesystem associate; + typeattribute tmp_t file_type; + typeattribute tmp_t polymember; + allow tmp_t tmpfs_t:filesystem associate; + typeattribute tmp_t tmpfile; + allow tmp_t tmp_t:filesystem associate; + allow tmp_t fs_t:filesystem associate; + allow tmp_t noxattrfs:filesystem associate; + typeattribute tmp_t file_type; + typeattribute tmp_t polyparent; + allow usr_t fs_t:filesystem associate; + allow usr_t noxattrfs:filesystem associate; + allow var_t fs_t:filesystem associate; + allow var_t noxattrfs:filesystem associate; + allow var_lib_t fs_t:filesystem associate; + allow var_lib_t noxattrfs:filesystem associate; + allow var_lock_t fs_t:filesystem associate; + allow var_lock_t noxattrfs:filesystem associate; + allow var_run_t fs_t:filesystem associate; + allow var_run_t noxattrfs:filesystem associate; + allow var_spool_t fs_t:filesystem associate; + allow var_spool_t noxattrfs:filesystem associate; + typeattribute var_spool_t file_type; + allow var_spool_t fs_t:filesystem associate; + allow var_spool_t noxattrfs:filesystem associate; + typeattribute var_spool_t file_type; + typeattribute var_spool_t polymember; + allow var_spool_t tmpfs_t:filesystem associate; + typeattribute var_spool_t tmpfile; + allow var_spool_t tmp_t:filesystem associate; + typeattribute fs_t filesystem_type; + allow fs_t self:filesystem associate; + typeattribute bdev_t filesystem_type; + allow bdev_t self:filesystem associate; + typeattribute binfmt_misc_fs_t filesystem_type; + allow binfmt_misc_fs_t self:filesystem associate; + allow binfmt_misc_fs_t fs_t:filesystem associate; + allow binfmt_misc_fs_t noxattrfs:filesystem associate; + typeattribute binfmt_misc_fs_t file_type; + typeattribute binfmt_misc_fs_t mountpoint; + typeattribute capifs_t filesystem_type; + allow capifs_t self:filesystem associate; + typeattribute configfs_t filesystem_type; + allow configfs_t self:filesystem associate; + typeattribute eventpollfs_t filesystem_type; + allow eventpollfs_t self:filesystem associate; + typeattribute futexfs_t filesystem_type; + allow futexfs_t self:filesystem associate; + typeattribute hugetlbfs_t filesystem_type; + allow hugetlbfs_t self:filesystem associate; + allow hugetlbfs_t fs_t:filesystem associate; + allow hugetlbfs_t noxattrfs:filesystem associate; + typeattribute hugetlbfs_t file_type; + typeattribute hugetlbfs_t mountpoint; + typeattribute inotifyfs_t filesystem_type; + allow inotifyfs_t self:filesystem associate; + typeattribute nfsd_fs_t filesystem_type; + allow nfsd_fs_t self:filesystem associate; + typeattribute ramfs_t filesystem_type; + allow ramfs_t self:filesystem associate; + typeattribute romfs_t filesystem_type; + allow romfs_t self:filesystem associate; + typeattribute rpc_pipefs_t filesystem_type; + allow rpc_pipefs_t self:filesystem associate; + typeattribute tmpfs_t filesystem_type; + allow tmpfs_t self:filesystem associate; + allow tmpfs_t fs_t:filesystem associate; + allow tmpfs_t noxattrfs:filesystem associate; + typeattribute tmpfs_t file_type; + allow tmpfs_t fs_t:filesystem associate; + allow tmpfs_t noxattrfs:filesystem associate; + typeattribute tmpfs_t file_type; + typeattribute tmpfs_t mountpoint; +allow tmpfs_t noxattrfs:filesystem associate; + typeattribute autofs_t filesystem_type; + allow autofs_t self:filesystem associate; + allow autofs_t fs_t:filesystem associate; + allow autofs_t noxattrfs:filesystem associate; + typeattribute autofs_t file_type; + typeattribute autofs_t mountpoint; + typeattribute cifs_t filesystem_type; + allow cifs_t self:filesystem associate; + typeattribute dosfs_t filesystem_type; + allow dosfs_t self:filesystem associate; +allow dosfs_t fs_t:filesystem associate; + typeattribute iso9660_t filesystem_type; + allow iso9660_t self:filesystem associate; +allow removable_t noxattrfs:filesystem associate; + typeattribute removable_t filesystem_type; + allow removable_t self:filesystem associate; + allow removable_t fs_t:filesystem associate; + allow removable_t noxattrfs:filesystem associate; + typeattribute removable_t file_type; + typeattribute removable_t usercanread; + typeattribute nfs_t filesystem_type; + allow nfs_t self:filesystem associate; + allow nfs_t fs_t:filesystem associate; + allow nfs_t noxattrfs:filesystem associate; + typeattribute nfs_t file_type; + typeattribute nfs_t mountpoint; +neverallow ~can_load_kernmodule self:capability sys_module; +role system_r; +role sysadm_r; +role staff_r; +role user_r; +role secadm_r; + typeattribute kernel_t domain; + allow kernel_t self:dir { read getattr lock search ioctl }; + allow kernel_t self:lnk_file { read getattr lock ioctl }; + allow kernel_t self:file { getattr read write append ioctl lock }; + allow kernel_t self:process { fork sigchld }; + role secadm_r types kernel_t; + role sysadm_r types kernel_t; + role user_r types kernel_t; + role staff_r types kernel_t; + typeattribute kernel_t privrangetrans; +role system_r types kernel_t; + typeattribute debugfs_t filesystem_type; + allow debugfs_t self:filesystem associate; +allow debugfs_t self:filesystem associate; + allow proc_t fs_t:filesystem associate; + allow proc_t noxattrfs:filesystem associate; + typeattribute proc_t file_type; + typeattribute proc_t mountpoint; + typeattribute proc_t filesystem_type; + allow proc_t self:filesystem associate; +neverallow ~can_receive_kernel_messages proc_kmsg_t:file ~getattr; +neverallow { domain -kern_unconfined } proc_kcore_t:file ~getattr; + allow sysctl_t fs_t:filesystem associate; + allow sysctl_t noxattrfs:filesystem associate; + typeattribute sysctl_t file_type; + typeattribute sysctl_t mountpoint; + allow sysctl_fs_t fs_t:filesystem associate; + allow sysctl_fs_t noxattrfs:filesystem associate; + typeattribute sysctl_fs_t file_type; + typeattribute sysctl_fs_t mountpoint; +allow kernel_t self:capability *; +allow kernel_t unlabeled_t:dir mounton; +allow kernel_t self:process ~{ ptrace setcurrent setexec setfscreate setrlimit execmem execstack execheap }; +allow kernel_t self:shm { associate getattr setattr create destroy read write lock unix_read unix_write }; +allow kernel_t self:sem { associate getattr setattr create destroy read write unix_read unix_write }; +allow kernel_t self:msg { send receive }; +allow kernel_t self:msgq { associate getattr setattr create destroy read write enqueue unix_read unix_write }; +allow kernel_t self:unix_dgram_socket { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } }; +allow kernel_t self:unix_stream_socket { { create { ioctl read getattr write setattr append bind connect getopt setopt shutdown } } listen accept }; +allow kernel_t self:unix_dgram_socket sendto; +allow kernel_t self:unix_stream_socket connectto; +allow kernel_t self:fifo_file { getattr read write append ioctl lock }; +allow kernel_t self:sock_file { read getattr lock ioctl }; +allow kernel_t self:fd use; +allow kernel_t proc_t:dir { read getattr lock search ioctl }; +allow kernel_t proc_t:{ lnk_file file } { read getattr lock ioctl }; +allow kernel_t proc_net_t:dir { read getattr lock search ioctl }; +allow kernel_t proc_net_t:file { read getattr lock ioctl }; +allow kernel_t proc_mdstat_t:file { read getattr lock ioctl }; +allow kernel_t proc_kcore_t:file getattr; +allow kernel_t proc_kmsg_t:file getattr; +allow kernel_t sysctl_t:dir { read getattr lock search ioctl }; +allow kernel_t sysctl_kernel_t:dir { read getattr lock search ioctl }; +allow kernel_t sysctl_kernel_t:file { read getattr lock ioctl }; +allow kernel_t unlabeled_t:fifo_file { getattr read write append ioctl lock }; + allow kernel_t unlabeled_t:association { sendto recvfrom }; + allow kernel_t netif_type:netif rawip_send; + allow kernel_t netif_type:netif rawip_recv; + allow kernel_t node_type:node rawip_send; + allow kernel_t node_type:node rawip_recv; + allow kernel_t netif_t:netif rawip_send; + allow kernel_t netif_type:netif { tcp_send tcp_recv }; + allow kernel_t node_type:node { tcp_send tcp_recv }; + allow kernel_t node_t:node rawip_send; + allow kernel_t multicast_node_t:node rawip_send; + allow kernel_t sysfs_t:dir { read getattr lock search ioctl }; + allow kernel_t sysfs_t:{ file lnk_file } { read getattr lock ioctl }; + allow kernel_t usbfs_t:dir search; + allow kernel_t filesystem_type:filesystem mount; + allow kernel_t security_t:dir { read search getattr }; + allow kernel_t security_t:file { getattr read write }; + typeattribute kernel_t can_load_policy; + if(!secure_mode_policyload) { + allow kernel_t security_t:security load_policy; + auditallow kernel_t security_t:security load_policy; + } + allow kernel_t device_t:dir { read getattr lock search ioctl }; + allow kernel_t device_t:lnk_file { getattr read }; + allow kernel_t console_device_t:chr_file { getattr read write append ioctl lock }; + allow kernel_t bin_t:dir { read getattr lock search ioctl }; + allow kernel_t bin_t:lnk_file { read getattr lock ioctl }; + allow kernel_t shell_exec_t:file { { read getattr lock execute ioctl } execute_no_trans }; + allow kernel_t sbin_t:dir { read getattr lock search ioctl }; + allow kernel_t bin_t:dir { read getattr lock search ioctl }; + allow kernel_t bin_t:lnk_file { read getattr lock ioctl }; + allow kernel_t bin_t:file { { read getattr lock execute ioctl } execute_no_trans }; + allow kernel_t domain:process signal; + allow kernel_t proc_t:dir search; + allow kernel_t domain:dir search; + allow kernel_t root_t:dir { read getattr lock search ioctl }; + allow kernel_t root_t:lnk_file { read getattr lock ioctl }; + allow kernel_t etc_t:dir { read getattr lock search ioctl }; + allow kernel_t home_root_t:dir { read getattr lock search ioctl }; + allow kernel_t usr_t:dir { read getattr lock search ioctl }; + allow kernel_t usr_t:{ file lnk_file } { read getattr lock ioctl }; + typeattribute kernel_t mlsprocread; + typeattribute kernel_t mlsprocwrite; + allow kernel_t self:capability *; + allow kernel_t self:fifo_file { create ioctl read getattr lock write setattr append link unlink rename }; + allow kernel_t self:process transition; + allow kernel_t self:file { getattr read write append ioctl lock }; + allow kernel_t self:nscd *; + allow kernel_t self:dbus *; + allow kernel_t self:passwd *; + allow kernel_t proc_type:{ dir file } *; + allow kernel_t sysctl_t:{ dir file } *; + allow kernel_t kernel_t:system *; + allow kernel_t unlabeled_t:{ dir file lnk_file sock_file fifo_file chr_file blk_file } *; + allow kernel_t unlabeled_t:filesystem *; + allow kernel_t unlabeled_t:association *; + typeattribute kernel_t can_load_kernmodule, can_receive_kernel_messages; + typeattribute kernel_t kern_unconfined; + allow kernel_t { proc_t proc_net_t }:dir search; + allow kernel_t sysctl_type:dir { read getattr lock search ioctl }; + allow kernel_t sysctl_type:file { { getattr read write append ioctl lock } setattr }; + allow kernel_t node_type:node *; + allow kernel_t netif_type:netif *; + allow kernel_t port_type:tcp_socket { send_msg recv_msg name_connect }; + allow kernel_t port_type:udp_socket { send_msg recv_msg }; + allow kernel_t port_type:{ tcp_socket udp_socket rawip_socket } name_bind; + allow kernel_t node_type:{ tcp_socket udp_socket rawip_socket } node_bind; + allow kernel_t unlabeled_t:association { sendto recvfrom }; + allow kernel_t device_node:{ chr_file blk_file } *; + allow kernel_t mtrr_device_t:{ dir file } *; + allow kernel_t self:capability sys_rawio; + typeattribute kernel_t memory_raw_write, memory_raw_read; + typeattribute kernel_t unconfined_domain_type; + typeattribute kernel_t can_change_process_identity; + typeattribute kernel_t can_change_process_role; + typeattribute kernel_t can_change_object_identity; + typeattribute kernel_t set_curr_context; + allow kernel_t domain:{ { tcp_socket udp_socket rawip_socket netlink_socket packet_socket unix_stream_socket unix_dgram_socket netlink_route_socket netlink_firewall_socket netlink_tcpdiag_socket netlink_nflog_socket netlink_xfrm_socket netlink_selinux_socket netlink_audit_socket netlink_ip6fw_socket netlink_dnrt_socket netlink_kobject_uevent_socket } socket key_socket } *; + allow kernel_t domain:fd use; + allow kernel_t domain:fifo_file { getattr read write append ioctl lock }; + allow kernel_t domain:process ~{ transition dyntransition execmem execstack execheap }; + allow kernel_t domain:{ sem msgq shm } *; + allow kernel_t domain:msg { send receive }; + allow kernel_t domain:dir { read getattr lock search ioctl }; + allow kernel_t domain:file { read getattr lock ioctl }; + allow kernel_t domain:lnk_file { read getattr lock ioctl }; + dontaudit kernel_t domain:dir { read getattr lock search ioctl }; + dontaudit kernel_t domain:lnk_file { read getattr lock ioctl }; + dontaudit kernel_t domain:file { read getattr lock ioctl }; + dontaudit kernel_t domain:sock_file { read getattr lock ioctl }; + dontaudit kernel_t domain:fifo_file { read getattr lock ioctl }; + allow kernel_t file_type:{ file chr_file } ~execmod; + allow kernel_t file_type:{ dir lnk_file sock_file fifo_file blk_file } *; + allow kernel_t file_type:filesystem *; + allow kernel_t file_type:{ unix_stream_socket unix_dgram_socket } name_bind; + if (allow_execmod) { + allow kernel_t file_type:file execmod; + } + allow kernel_t filesystem_type:filesystem *; + allow kernel_t filesystem_type:{ dir file lnk_file sock_file fifo_file chr_file blk_file } *; + allow kernel_t security_t:dir { getattr search read }; + allow kernel_t security_t:file { getattr read write }; + typeattribute kernel_t can_load_policy, can_setenforce, can_setsecparam; + if(!secure_mode_policyload) { + allow kernel_t security_t:security *; + auditallow kernel_t security_t:security { load_policy setenforce setbool }; + } + if (allow_execheap) { + allow kernel_t self:process execheap; + } + if (allow_execmem) { + allow kernel_t self:process execmem; + } + if (allow_execmem && allow_execstack) { + allow kernel_t self:process execstack; + auditallow kernel_t self:process execstack; + } else { + } + if (allow_execheap) { + auditallow kernel_t self:process execheap; + } + if (allow_execmem) { + auditallow kernel_t self:process execmem; + } + if (read_default_t) { + allow kernel_t default_t:dir { read getattr lock search ioctl }; + allow kernel_t default_t:file { read getattr lock ioctl }; + allow kernel_t default_t:lnk_file { read getattr lock ioctl }; + allow kernel_t default_t:sock_file { read getattr lock ioctl }; + allow kernel_t default_t:fifo_file { read getattr lock ioctl }; + } + allow unlabeled_t self:filesystem associate; +range_transition getty_t login_exec_t s0 - s0:c0.c255; +range_transition init_t xdm_exec_t s0 - s0:c0.c255; +range_transition initrc_t crond_exec_t s0 - s0:c0.c255; +range_transition initrc_t cupsd_exec_t s0 - s0:c0.c255; +range_transition initrc_t sshd_exec_t s0 - s0:c0.c255; +range_transition initrc_t udev_exec_t s0 - s0:c0.c255; +range_transition initrc_t xdm_exec_t s0 - s0:c0.c255; +range_transition kernel_t udev_exec_t s0 - s0:c0.c255; +range_transition unconfined_t su_exec_t s0 - s0:c0.c255; +range_transition unconfined_t initrc_exec_t s0; + typeattribute security_t filesystem_type; + allow security_t self:filesystem associate; + typeattribute security_t mlstrustedobject; +neverallow ~can_load_policy security_t:security load_policy; +neverallow ~can_setenforce security_t:security setenforce; +neverallow ~can_setsecparam security_t:security setsecparam; + typeattribute bsdpty_device_t device_node; + allow bsdpty_device_t fs_t:filesystem associate; + allow bsdpty_device_t tmpfs_t:filesystem associate; + allow bsdpty_device_t tmp_t:filesystem associate; + typeattribute console_device_t device_node; + allow console_device_t fs_t:filesystem associate; + allow console_device_t tmpfs_t:filesystem associate; + allow console_device_t tmp_t:filesystem associate; + allow devpts_t fs_t:filesystem associate; + allow devpts_t noxattrfs:filesystem associate; + typeattribute devpts_t file_type; + typeattribute devpts_t mountpoint; + allow devpts_t tmpfs_t:filesystem associate; + allow devpts_t tmp_t:filesystem associate; + typeattribute devpts_t filesystem_type; + allow devpts_t self:filesystem associate; + typeattribute devpts_t ttynode, ptynode; + typeattribute devtty_t device_node; + allow devtty_t fs_t:filesystem associate; + allow devtty_t tmpfs_t:filesystem associate; + allow devtty_t tmp_t:filesystem associate; + typeattribute devtty_t mlstrustedobject; + typeattribute ptmx_t device_node; + allow ptmx_t fs_t:filesystem associate; + allow ptmx_t tmpfs_t:filesystem associate; + allow ptmx_t tmp_t:filesystem associate; + typeattribute ptmx_t mlstrustedobject; + typeattribute tty_device_t device_node; + allow tty_device_t fs_t:filesystem associate; + allow tty_device_t tmpfs_t:filesystem associate; + allow tty_device_t tmp_t:filesystem associate; + typeattribute tty_device_t ttynode; + typeattribute usbtty_device_t device_node; + allow usbtty_device_t fs_t:filesystem associate; + allow usbtty_device_t tmpfs_t:filesystem associate; + allow usbtty_device_t tmp_t:filesystem associate; +user system_u roles { system_r } level s0 range s0 - s0:c0.c255; +user user_u roles { user_r sysadm_r system_r } level s0 range s0 - s0:c0.c255; + user root roles { user_r sysadm_r system_r } level s0 range s0 - s0:c0.c255; +constrain process transition + ( u1 == u2 + or t1 == can_change_process_identity +); +constrain process transition + ( r1 == r2 + or t1 == can_change_process_role +); +constrain process dyntransition + ( u1 == u2 and r1 == r2 ); +constrain { dir file lnk_file sock_file fifo_file chr_file blk_file } { create relabelto relabelfrom } + ( u1 == u2 or t1 == can_change_object_identity ); +constrain { tcp_socket udp_socket rawip_socket netlink_socket packet_socket unix_stream_socket unix_dgram_socket netlink_route_socket netlink_firewall_socket netlink_tcpdiag_socket netlink_nflog_socket netlink_xfrm_socket netlink_selinux_socket netlink_audit_socket netlink_ip6fw_socket netlink_dnrt_socket netlink_kobject_uevent_socket } { create relabelto relabelfrom } + ( u1 == u2 or t1 == can_change_object_identity ); +sid port system_u:object_r:port_t:s0 +sid node system_u:object_r:node_t:s0 +sid netif system_u:object_r:netif_t:s0 +sid devnull system_u:object_r:null_device_t:s0 +sid file system_u:object_r:file_t:s0 +sid fs system_u:object_r:fs_t:s0 +sid kernel system_u:system_r:kernel_t:s0 +sid sysctl system_u:object_r:sysctl_t:s0 +sid unlabeled system_u:object_r:unlabeled_t:s0 +sid any_socket system_u:object_r:unlabeled_t:s0 +sid file_labels system_u:object_r:unlabeled_t:s0 +sid icmp_socket system_u:object_r:unlabeled_t:s0 +sid igmp_packet system_u:object_r:unlabeled_t:s0 +sid init system_u:object_r:unlabeled_t:s0 +sid kmod system_u:object_r:unlabeled_t:s0 +sid netmsg system_u:object_r:unlabeled_t:s0 +sid policy system_u:object_r:unlabeled_t:s0 +sid scmp_packet system_u:object_r:unlabeled_t:s0 +sid sysctl_modprobe system_u:object_r:unlabeled_t:s0 +sid sysctl_fs system_u:object_r:unlabeled_t:s0 +sid sysctl_kernel system_u:object_r:unlabeled_t:s0 +sid sysctl_net system_u:object_r:unlabeled_t:s0 +sid sysctl_net_unix system_u:object_r:unlabeled_t:s0 +sid sysctl_vm system_u:object_r:unlabeled_t:s0 +sid sysctl_dev system_u:object_r:unlabeled_t:s0 +sid tcp_socket system_u:object_r:unlabeled_t:s0 +sid security system_u:object_r:security_t:s0 +fs_use_xattr ext2 system_u:object_r:fs_t:s0; +fs_use_xattr ext3 system_u:object_r:fs_t:s0; +fs_use_xattr gfs system_u:object_r:fs_t:s0; +fs_use_xattr jfs system_u:object_r:fs_t:s0; +fs_use_xattr reiserfs system_u:object_r:fs_t:s0; +fs_use_xattr xfs system_u:object_r:fs_t:s0; +fs_use_task pipefs system_u:object_r:fs_t:s0; +fs_use_task sockfs system_u:object_r:fs_t:s0; +fs_use_trans mqueue system_u:object_r:tmpfs_t:s0; +fs_use_trans shm system_u:object_r:tmpfs_t:s0; +fs_use_trans tmpfs system_u:object_r:tmpfs_t:s0; +fs_use_trans devpts system_u:object_r:devpts_t:s0; +genfscon proc /mtrr system_u:object_r:mtrr_device_t:s0 +genfscon sysfs / system_u:object_r:sysfs_t:s0 +genfscon usbfs / system_u:object_r:usbfs_t:s0 +genfscon usbdevfs / system_u:object_r:usbfs_t:s0 +genfscon rootfs / system_u:object_r:root_t:s0 +genfscon bdev / system_u:object_r:bdev_t:s0 +genfscon binfmt_misc / system_u:object_r:binfmt_misc_fs_t:s0 +genfscon capifs / system_u:object_r:capifs_t:s0 +genfscon configfs / system_u:object_r:configfs_t:s0 +genfscon eventpollfs / system_u:object_r:eventpollfs_t:s0 +genfscon futexfs / system_u:object_r:futexfs_t:s0 +genfscon hugetlbfs / system_u:object_r:hugetlbfs_t:s0 +genfscon inotifyfs / system_u:object_r:inotifyfs_t:s0 +genfscon nfsd / system_u:object_r:nfsd_fs_t:s0 +genfscon ramfs / system_u:object_r:ramfs_t:s0 +genfscon romfs / system_u:object_r:romfs_t:s0 +genfscon cramfs / system_u:object_r:romfs_t:s0 +genfscon rpc_pipefs / system_u:object_r:rpc_pipefs_t:s0 +genfscon autofs / system_u:object_r:autofs_t:s0 +genfscon automount / system_u:object_r:autofs_t:s0 +genfscon cifs / system_u:object_r:cifs_t:s0 +genfscon smbfs / system_u:object_r:cifs_t:s0 +genfscon fat / system_u:object_r:dosfs_t:s0 +genfscon msdos / system_u:object_r:dosfs_t:s0 +genfscon ntfs / system_u:object_r:dosfs_t:s0 +genfscon vfat / system_u:object_r:dosfs_t:s0 +genfscon iso9660 / system_u:object_r:iso9660_t:s0 +genfscon udf / system_u:object_r:iso9660_t:s0 +genfscon nfs / system_u:object_r:nfs_t:s0 +genfscon nfs4 / system_u:object_r:nfs_t:s0 +genfscon afs / system_u:object_r:nfs_t:s0 +genfscon hfsplus / system_u:object_r:nfs_t:s0 +genfscon debugfs / system_u:object_r:debugfs_t:s0 +genfscon proc / system_u:object_r:proc_t:s0 +genfscon proc /sysvipc system_u:object_r:proc_t:s0 +genfscon proc /kmsg system_u:object_r:proc_kmsg_t:s0 +genfscon proc /kcore system_u:object_r:proc_kcore_t:s0 +genfscon proc /mdstat system_u:object_r:proc_mdstat_t:s0 +genfscon proc /net system_u:object_r:proc_net_t:s0 +genfscon proc /xen system_u:object_r:proc_xen_t:s0 +genfscon proc /sys system_u:object_r:sysctl_t:s0 +genfscon proc /irq system_u:object_r:sysctl_irq_t:s0 +genfscon proc /net/rpc system_u:object_r:sysctl_rpc_t:s0 +genfscon proc /sys/fs system_u:object_r:sysctl_fs_t:s0 +genfscon proc /sys/kernel system_u:object_r:sysctl_kernel_t:s0 +genfscon proc /sys/kernel/modprobe system_u:object_r:sysctl_modprobe_t:s0 +genfscon proc /sys/kernel/hotplug system_u:object_r:sysctl_hotplug_t:s0 +genfscon proc /sys/net system_u:object_r:sysctl_net_t:s0 +genfscon proc /sys/net/unix system_u:object_r:sysctl_net_unix_t:s0 +genfscon proc /sys/vm system_u:object_r:sysctl_vm_t:s0 +genfscon proc /sys/dev system_u:object_r:sysctl_dev_t:s0 +genfscon selinuxfs / system_u:object_r:security_t:s0 +portcon udp 7007 system_u:object_r:afs_bos_port_t:s0 +portcon tcp 2040 system_u:object_r:afs_fs_port_t:s0 +portcon udp 7000 system_u:object_r:afs_fs_port_t:s0 +portcon udp 7005 system_u:object_r:afs_fs_port_t:s0 +portcon udp 7004 system_u:object_r:afs_ka_port_t:s0 +portcon udp 7002 system_u:object_r:afs_pt_port_t:s0 +portcon udp 7003 system_u:object_r:afs_vl_port_t:s0 +portcon udp 10080 system_u:object_r:amanda_port_t:s0 +portcon tcp 10080 system_u:object_r:amanda_port_t:s0 +portcon udp 10081 system_u:object_r:amanda_port_t:s0 +portcon tcp 10081 system_u:object_r:amanda_port_t:s0 +portcon tcp 10082 system_u:object_r:amanda_port_t:s0 +portcon tcp 10083 system_u:object_r:amanda_port_t:s0 +portcon tcp 10024 system_u:object_r:amavisd_recv_port_t:s0 +portcon tcp 10025 system_u:object_r:amavisd_send_port_t:s0 +portcon tcp 1720 system_u:object_r:asterisk_port_t:s0 +portcon udp 2427 system_u:object_r:asterisk_port_t:s0 +portcon udp 2727 system_u:object_r:asterisk_port_t:s0 +portcon udp 4569 system_u:object_r:asterisk_port_t:s0 +portcon udp 5060 system_u:object_r:asterisk_port_t:s0 +portcon tcp 113 system_u:object_r:auth_port_t:s0 +portcon tcp 179 system_u:object_r:bgp_port_t:s0 +portcon udp 179 system_u:object_r:bgp_port_t:s0 +portcon tcp 3310 system_u:object_r:clamd_port_t:s0 +portcon udp 4041 system_u:object_r:clockspeed_port_t:s0 +portcon udp 512 system_u:object_r:comsat_port_t:s0 +portcon tcp 2401 system_u:object_r:cvs_port_t:s0 +portcon udp 2401 system_u:object_r:cvs_port_t:s0 +portcon udp 6276 system_u:object_r:dcc_port_t:s0 +portcon udp 6277 system_u:object_r:dcc_port_t:s0 +portcon tcp 1178 system_u:object_r:dbskkd_port_t:s0 +portcon udp 68 system_u:object_r:dhcpc_port_t:s0 +portcon udp 67 system_u:object_r:dhcpd_port_t:s0 +portcon tcp 647 system_u:object_r:dhcpd_port_t:s0 +portcon udp 647 system_u:object_r:dhcpd_port_t:s0 +portcon tcp 847 system_u:object_r:dhcpd_port_t:s0 +portcon udp 847 system_u:object_r:dhcpd_port_t:s0 +portcon tcp 2628 system_u:object_r:dict_port_t:s0 +portcon tcp 3632 system_u:object_r:distccd_port_t:s0 +portcon udp 53 system_u:object_r:dns_port_t:s0 +portcon tcp 53 system_u:object_r:dns_port_t:s0 +portcon tcp 79 system_u:object_r:fingerd_port_t:s0 +portcon tcp 20 system_u:object_r:ftp_data_port_t:s0 +portcon tcp 21 system_u:object_r:ftp_port_t:s0 +portcon udp 1718 system_u:object_r:gatekeeper_port_t:s0 +portcon udp 1719 system_u:object_r:gatekeeper_port_t:s0 +portcon tcp 1721 system_u:object_r:gatekeeper_port_t:s0 +portcon tcp 7000 system_u:object_r:gatekeeper_port_t:s0 +portcon tcp 1213 system_u:object_r:giftd_port_t:s0 +portcon tcp 70 system_u:object_r:gopher_port_t:s0 +portcon udp 70 system_u:object_r:gopher_port_t:s0 +portcon tcp 3128 system_u:object_r:http_cache_port_t:s0 +portcon udp 3130 system_u:object_r:http_cache_port_t:s0 +portcon tcp 8080 system_u:object_r:http_cache_port_t:s0 +portcon tcp 8118 system_u:object_r:http_cache_port_t:s0 +portcon tcp 80 system_u:object_r:http_port_t:s0 +portcon tcp 443 system_u:object_r:http_port_t:s0 +portcon tcp 488 system_u:object_r:http_port_t:s0 +portcon tcp 8008 system_u:object_r:http_port_t:s0 +portcon tcp 9050 system_u:object_r:http_port_t:s0 +portcon tcp 5335 system_u:object_r:howl_port_t:s0 +portcon udp 5353 system_u:object_r:howl_port_t:s0 +portcon tcp 50000 system_u:object_r:hplip_port_t:s0 +portcon tcp 50002 system_u:object_r:hplip_port_t:s0 +portcon tcp 9010 system_u:object_r:i18n_input_port_t:s0 +portcon tcp 5323 system_u:object_r:imaze_port_t:s0 +portcon udp 5323 system_u:object_r:imaze_port_t:s0 +portcon tcp 7 system_u:object_r:inetd_child_port_t:s0 +portcon udp 7 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 9 system_u:object_r:inetd_child_port_t:s0 +portcon udp 9 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 13 system_u:object_r:inetd_child_port_t:s0 +portcon udp 13 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 19 system_u:object_r:inetd_child_port_t:s0 +portcon udp 19 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 37 system_u:object_r:inetd_child_port_t:s0 +portcon udp 37 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 512 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 543 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 544 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 891 system_u:object_r:inetd_child_port_t:s0 +portcon udp 891 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 892 system_u:object_r:inetd_child_port_t:s0 +portcon udp 892 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 2105 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 5666 system_u:object_r:inetd_child_port_t:s0 +portcon tcp 119 system_u:object_r:innd_port_t:s0 +portcon tcp 631 system_u:object_r:ipp_port_t:s0 +portcon udp 631 system_u:object_r:ipp_port_t:s0 +portcon tcp 6667 system_u:object_r:ircd_port_t:s0 +portcon udp 500 system_u:object_r:isakmp_port_t:s0 +portcon tcp 5222 system_u:object_r:jabber_client_port_t:s0 +portcon tcp 5223 system_u:object_r:jabber_client_port_t:s0 +portcon tcp 5269 system_u:object_r:jabber_interserver_port_t:s0 +portcon tcp 464 system_u:object_r:kerberos_admin_port_t:s0 +portcon udp 464 system_u:object_r:kerberos_admin_port_t:s0 +portcon tcp 749 system_u:object_r:kerberos_admin_port_t:s0 +portcon tcp 4444 system_u:object_r:kerberos_master_port_t:s0 +portcon udp 4444 system_u:object_r:kerberos_master_port_t:s0 +portcon tcp 88 system_u:object_r:kerberos_port_t:s0 +portcon udp 88 system_u:object_r:kerberos_port_t:s0 +portcon tcp 750 system_u:object_r:kerberos_port_t:s0 +portcon udp 750 system_u:object_r:kerberos_port_t:s0 +portcon udp 517 system_u:object_r:ktalkd_port_t:s0 +portcon udp 518 system_u:object_r:ktalkd_port_t:s0 +portcon tcp 389 system_u:object_r:ldap_port_t:s0 +portcon udp 389 system_u:object_r:ldap_port_t:s0 +portcon tcp 636 system_u:object_r:ldap_port_t:s0 +portcon udp 636 system_u:object_r:ldap_port_t:s0 +portcon tcp 2000 system_u:object_r:mail_port_t:s0 +portcon tcp 1234 system_u:object_r:monopd_port_t:s0 +portcon tcp 3306 system_u:object_r:mysqld_port_t:s0 +portcon tcp 1241 system_u:object_r:nessus_port_t:s0 +portcon udp 137 system_u:object_r:nmbd_port_t:s0 +portcon udp 138 system_u:object_r:nmbd_port_t:s0 +portcon udp 139 system_u:object_r:nmbd_port_t:s0 +portcon udp 123 system_u:object_r:ntp_port_t:s0 +portcon udp 5000 system_u:object_r:openvpn_port_t:s0 +portcon tcp 5988 system_u:object_r:pegasus_http_port_t:s0 +portcon tcp 5989 system_u:object_r:pegasus_https_port_t:s0 +portcon tcp 106 system_u:object_r:pop_port_t:s0 +portcon tcp 109 system_u:object_r:pop_port_t:s0 +portcon tcp 110 system_u:object_r:pop_port_t:s0 +portcon tcp 143 system_u:object_r:pop_port_t:s0 +portcon tcp 220 system_u:object_r:pop_port_t:s0 +portcon tcp 993 system_u:object_r:pop_port_t:s0 +portcon tcp 995 system_u:object_r:pop_port_t:s0 +portcon tcp 1109 system_u:object_r:pop_port_t:s0 +portcon udp 111 system_u:object_r:portmap_port_t:s0 +portcon tcp 111 system_u:object_r:portmap_port_t:s0 +portcon tcp 5432 system_u:object_r:postgresql_port_t:s0 +portcon tcp 60000 system_u:object_r:postgrey_port_t:s0 +portcon tcp 515 system_u:object_r:printer_port_t:s0 +portcon tcp 5703 system_u:object_r:ptal_port_t:s0 +portcon udp 4011 system_u:object_r:pxe_port_t:s0 +portcon udp 24441 system_u:object_r:pyzor_port_t:s0 +portcon udp 1646 system_u:object_r:radacct_port_t:s0 +portcon udp 1813 system_u:object_r:radacct_port_t:s0 +portcon udp 1645 system_u:object_r:radius_port_t:s0 +portcon udp 1812 system_u:object_r:radius_port_t:s0 +portcon tcp 2703 system_u:object_r:razor_port_t:s0 +portcon tcp 513 system_u:object_r:rlogind_port_t:s0 +portcon tcp 953 system_u:object_r:rndc_port_t:s0 +portcon udp 520 system_u:object_r:router_port_t:s0 +portcon tcp 514 system_u:object_r:rsh_port_t:s0 +portcon tcp 873 system_u:object_r:rsync_port_t:s0 +portcon udp 873 system_u:object_r:rsync_port_t:s0 +portcon tcp 137-139 system_u:object_r:smbd_port_t:s0 +portcon tcp 445 system_u:object_r:smbd_port_t:s0 +portcon tcp 25 system_u:object_r:smtp_port_t:s0 +portcon tcp 465 system_u:object_r:smtp_port_t:s0 +portcon tcp 587 system_u:object_r:smtp_port_t:s0 +portcon udp 161 system_u:object_r:snmp_port_t:s0 +portcon udp 162 system_u:object_r:snmp_port_t:s0 +portcon tcp 199 system_u:object_r:snmp_port_t:s0 +portcon tcp 783 system_u:object_r:spamd_port_t:s0 +portcon tcp 22 system_u:object_r:ssh_port_t:s0 +portcon tcp 8000 system_u:object_r:soundd_port_t:s0 +portcon tcp 9433 system_u:object_r:soundd_port_t:s0 +portcon tcp 901 system_u:object_r:swat_port_t:s0 +portcon udp 514 system_u:object_r:syslogd_port_t:s0 +portcon tcp 23 system_u:object_r:telnetd_port_t:s0 +portcon udp 69 system_u:object_r:tftp_port_t:s0 +portcon tcp 8081 system_u:object_r:transproxy_port_t:s0 +portcon tcp 540 system_u:object_r:uucpd_port_t:s0 +portcon tcp 5900 system_u:object_r:vnc_port_t:s0 +portcon tcp 6001 system_u:object_r:xserver_port_t:s0 +portcon tcp 6002 system_u:object_r:xserver_port_t:s0 +portcon tcp 6003 system_u:object_r:xserver_port_t:s0 +portcon tcp 6004 system_u:object_r:xserver_port_t:s0 +portcon tcp 6005 system_u:object_r:xserver_port_t:s0 +portcon tcp 6006 system_u:object_r:xserver_port_t:s0 +portcon tcp 6007 system_u:object_r:xserver_port_t:s0 +portcon tcp 6008 system_u:object_r:xserver_port_t:s0 +portcon tcp 6009 system_u:object_r:xserver_port_t:s0 +portcon tcp 6010 system_u:object_r:xserver_port_t:s0 +portcon tcp 6011 system_u:object_r:xserver_port_t:s0 +portcon tcp 6012 system_u:object_r:xserver_port_t:s0 +portcon tcp 6013 system_u:object_r:xserver_port_t:s0 +portcon tcp 6014 system_u:object_r:xserver_port_t:s0 +portcon tcp 6015 system_u:object_r:xserver_port_t:s0 +portcon tcp 6016 system_u:object_r:xserver_port_t:s0 +portcon tcp 6017 system_u:object_r:xserver_port_t:s0 +portcon tcp 6018 system_u:object_r:xserver_port_t:s0 +portcon tcp 6019 system_u:object_r:xserver_port_t:s0 +portcon tcp 8002 system_u:object_r:xen_port_t:s0 +portcon tcp 2601 system_u:object_r:zebra_port_t:s0 +portcon tcp 8021 system_u:object_r:zope_port_t:s0 +portcon tcp 1-1023 system_u:object_r:reserved_port_t:s0 +portcon udp 1-1023 system_u:object_r:reserved_port_t:s0 +nodecon :: ffff:ffff:ffff:ffff:ffff:ffff:: system_u:object_r:compat_ipv4_node_t:s0 +nodecon 0.0.0.0 255.255.255.255 system_u:object_r:inaddr_any_node_t:s0 +nodecon fe80:: ffff:ffff:ffff:ffff:: system_u:object_r:link_local_node_t:s0 +nodecon 127.0.0.1 255.255.255.255 system_u:object_r:lo_node_t:s0 +nodecon ::ffff:0000:0000 ffff:ffff:ffff:ffff:ffff:ffff:: system_u:object_r:mapped_ipv4_node_t:s0 +nodecon ff00:: ff00:: system_u:object_r:multicast_node_t:s0 +nodecon fec0:: ffc0:: system_u:object_r:site_local_node_t:s0 +nodecon :: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system_u:object_r:unspec_node_t:s0 diff --git a/kernel/libsepol/tests/policies/test-deps/base-metreq.conf b/kernel/libsepol/tests/policies/test-deps/base-metreq.conf new file mode 100644 index 00000000..b7528dde --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/base-metreq.conf @@ -0,0 +1,523 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +#################################### +#################################### +##################################### +# TE RULES +attribute domain; +attribute system; +attribute foo; +attribute num; +attribute num_exec; +attribute files; + +type net_foo_t, foo; +type sys_foo_t, foo, system; +role system_r; +role system_r types sys_foo_t; + +type user_t, domain; +role user_r; +role user_r types user_t; + +type sysadm_t, domain, system; +role sysadm_r; +role sysadm_r types sysadm_t; + +type system_t, domain, system, foo; +role system_r; +role system_r types { system_t sys_foo_t }; + +type file_t; +type file_exec_t, files; +type fs_t; + +# Make this decl easy to find +type base_global_decl_t; + +# Actually used in module tests +type type_req_t; +attribute attr_req; +bool bool_req false; +role role_req_r; + + +allow sysadm_t file_exec_t: file { execute read write ioctl lock entrypoint }; + +optional { + require { + type base_optional_1, base_optional_2; + } + allow base_optional_1 base_optional_2 : file { read write }; +} + +##################################### +# Role Allow +allow user_r sysadm_r; + +#################################### +# Booleans +bool allow_ypbind true; +bool secure_mode false; +bool allow_execheap false; +bool allow_execmem true; +bool allow_execmod false; +bool allow_execstack true; +bool optional_bool_1 true; +bool optional_bool_2 false; + +##################################### +# users +gen_user(system_u,, system_r, s0, s0 - s0:c0.c23) +gen_user(root,, user_r sysadm_r, s0, s0 - s0:c0.c23) +gen_user(joe,, user_r, s0, s0 - s0:c0.c23) + +##################################### +# constraints + + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(system_u:system_r:sys_foo_t, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr ext3 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr reiserfs gen_context(system_u:object_r:fs_t, s0); + + +genfscon proc / gen_context(system_u:object_r:sys_foo_t, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 system_u:object_r:net_foo_t:s0 + +#netifcon lo system_u:object_r:net_foo_t system_u:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 system_u:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(system_u:object_r:net_foo_t, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-deps/base-notmetreq.conf b/kernel/libsepol/tests/policies/test-deps/base-notmetreq.conf new file mode 100644 index 00000000..eee36dca --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/base-notmetreq.conf @@ -0,0 +1,510 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +#################################### +#################################### +##################################### +# TE RULES +attribute domain; +attribute system; +attribute foo; +attribute num; +attribute num_exec; +attribute files; + +type net_foo_t, foo; +type sys_foo_t, foo, system; +role system_r; +role system_r types sys_foo_t; + +type user_t, domain; +role user_r; +role user_r types user_t; + +type sysadm_t, domain, system; +role sysadm_r; +role sysadm_r types sysadm_t; + +type system_t, domain, system, foo; +role system_r; +role system_r types { system_t sys_foo_t }; + +type file_t; +type file_exec_t, files; +type fs_t; +type base_optional_1; +type base_optional_2; + +allow sysadm_t file_exec_t: file { execute read write ioctl lock entrypoint }; + +optional { + require { + type base_optional_1, base_optional_2; + } + allow base_optional_1 base_optional_2 : file { read write }; +} + +##################################### +# Role Allow +allow user_r sysadm_r; + +#################################### +# Booleans +bool allow_ypbind true; +bool secure_mode false; +bool allow_execheap false; +bool allow_execmem true; +bool allow_execmod false; +bool allow_execstack true; +bool optional_bool_1 true; +bool optional_bool_2 false; + +##################################### +# users +gen_user(system_u,, system_r, s0, s0 - s0:c0.c23) +gen_user(root,, user_r sysadm_r, s0, s0 - s0:c0.c23) +gen_user(joe,, user_r, s0, s0 - s0:c0.c23) + +##################################### +# constraints + + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(system_u:system_r:sys_foo_t, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr ext3 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr reiserfs gen_context(system_u:object_r:fs_t, s0); + + +genfscon proc / gen_context(system_u:object_r:sys_foo_t, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 system_u:object_r:net_foo_t:s0 + +#netifcon lo system_u:object_r:net_foo_t system_u:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 system_u:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(system_u:object_r:net_foo_t, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-attr-global.conf b/kernel/libsepol/tests/policies/test-deps/modreq-attr-global.conf new file mode 100644 index 00000000..92f6b307 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-attr-global.conf @@ -0,0 +1,10 @@ +module modreq_attr_global 1.0; + +require { + attribute attr_req; +} + +type mod_global_t; + +type new_t, attr_req; + diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-attr-opt.conf b/kernel/libsepol/tests/policies/test-deps/modreq-attr-opt.conf new file mode 100644 index 00000000..b970c1d6 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-attr-opt.conf @@ -0,0 +1,16 @@ +module modreq_attr_opt 1.0; + +require { + class file {read write}; + +} + +type mod_global_t; + +optional { + require { + attribute attr_req; + } + type mod_opt_t; + type new_t, attr_req; +} diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-bool-global.conf b/kernel/libsepol/tests/policies/test-deps/modreq-bool-global.conf new file mode 100644 index 00000000..4ef0cc9e --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-bool-global.conf @@ -0,0 +1,15 @@ +module modreq_bool_global 1.0; + +require { + bool bool_req; + class file { read write }; +} + +type mod_global_t; + +type a_t; +type b_t; + +if (bool_req) { + allow a_t b_t : file { read write }; +} diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-bool-opt.conf b/kernel/libsepol/tests/policies/test-deps/modreq-bool-opt.conf new file mode 100644 index 00000000..27af4f20 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-bool-opt.conf @@ -0,0 +1,22 @@ +module modreq_bool_opt 1.0; + +require { + class file {read write}; + +} + +type mod_global_t; + +optional { + require { + bool bool_req; + } + + type a_t; + type b_t; + type mod_opt_t; + + if (bool_req) { + allow a_t b_t : file { read write }; + } +} diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-obj-global.conf b/kernel/libsepol/tests/policies/test-deps/modreq-obj-global.conf new file mode 100644 index 00000000..e9eba777 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-obj-global.conf @@ -0,0 +1,13 @@ +module modreq_obj_global 1.0; + +require { + class sem { create destroy }; +} + +type mod_global_t; + +type mod_foo_t; +type mod_bar_t; + +allow mod_foo_t mod_bar_t : sem { create destroy }; + diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-obj-opt.conf b/kernel/libsepol/tests/policies/test-deps/modreq-obj-opt.conf new file mode 100644 index 00000000..67a41a46 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-obj-opt.conf @@ -0,0 +1,20 @@ +module modreq_obj_global 1.0; + +require { + class file { read }; +} + +type mod_global_t; + +type mod_foo_t; +type mod_bar_t; + +optional { + require { + class sem { create destroy }; + } + + type mod_opt_t; + + allow mod_foo_t mod_bar_t : sem { create destroy }; +} diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-perm-global.conf b/kernel/libsepol/tests/policies/test-deps/modreq-perm-global.conf new file mode 100644 index 00000000..941ca96c --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-perm-global.conf @@ -0,0 +1,10 @@ +module modreq_perm_global 1.0; + +require { + class msg { send receive }; +} + +type mod_global_t; +type a_t; +type b_t; +allow a_t b_t: msg { send receive }; diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-perm-opt.conf b/kernel/libsepol/tests/policies/test-deps/modreq-perm-opt.conf new file mode 100644 index 00000000..43a3f97a --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-perm-opt.conf @@ -0,0 +1,18 @@ +module modreq_perm_opt 1.0; + +require { + class file { read write }; +} + +type mod_global_t; + +optional { + require { + class msg { send receive }; + } + + type mod_opt_t; + type a_mod_t; + type b_mod_t; + allow a_mod_t b_mod_t: msg { send receive }; +} diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-role-global.conf b/kernel/libsepol/tests/policies/test-deps/modreq-role-global.conf new file mode 100644 index 00000000..01fd3ecd --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-role-global.conf @@ -0,0 +1,13 @@ +module modreq_role_global 1.0; + +require { + role role_req_r, user_r; +} + +type mod_global_t; + +type a_t; + +# role role_req_r types a_t; +allow role_req_r user_r; + diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-role-opt.conf b/kernel/libsepol/tests/policies/test-deps/modreq-role-opt.conf new file mode 100644 index 00000000..532a77e6 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-role-opt.conf @@ -0,0 +1,17 @@ +module modreq_role_opt 1.0; + +require { + class file {read write}; + +} + +type mod_global_t; + +optional { + require { + role role_req_r, user_r; + } + type mod_opt_t; + + allow role_req_r user_r; +} diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-type-global.conf b/kernel/libsepol/tests/policies/test-deps/modreq-type-global.conf new file mode 100644 index 00000000..e5704a3e --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-type-global.conf @@ -0,0 +1,12 @@ +module modreq_type_global 1.0; + +require { + type type_req_t; + class file { read write }; +} + +type mod_global_t; + +type test_t; + +allow test_t type_req_t : file { read write }; diff --git a/kernel/libsepol/tests/policies/test-deps/modreq-type-opt.conf b/kernel/libsepol/tests/policies/test-deps/modreq-type-opt.conf new file mode 100644 index 00000000..65071d78 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/modreq-type-opt.conf @@ -0,0 +1,16 @@ +module modreq_type_opt 1.0; + +require { + type file_t; + class file { read write }; +} + +type mod_global_t; + +optional { + require { + type type_req_t; + } + type mod_opt_t; + allow type_req_t file_t : file { read write }; +} \ No newline at end of file diff --git a/kernel/libsepol/tests/policies/test-deps/module.conf b/kernel/libsepol/tests/policies/test-deps/module.conf new file mode 100644 index 00000000..1971e4c6 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/module.conf @@ -0,0 +1,20 @@ +module my_module 1.0; + +require { + bool secure_mode; + type system_t, sysadm_t, file_t; + attribute domain; + role system_r; + class file {read write}; + +} + +type new_t, domain; +role system_r types new_t; + +allow system_t file_t : file { read write }; + +if (secure_mode) +{ + allow sysadm_t file_t : file { read write }; +} diff --git a/kernel/libsepol/tests/policies/test-deps/small-base.conf b/kernel/libsepol/tests/policies/test-deps/small-base.conf new file mode 100644 index 00000000..98f49c23 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-deps/small-base.conf @@ -0,0 +1,511 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +#################################### +#################################### +##################################### +# TE RULES +attribute domain; +attribute system; +attribute foo; +attribute num; +attribute num_exec; +attribute files; + +type net_foo_t, foo; +type sys_foo_t, foo, system; +role system_r types sys_foo_t; + +type user_t, domain; +role user_r types user_t; + +type sysadm_t, domain, system; +role sysadm_r types sysadm_t; + +type system_t, domain, system, foo; +role system_r types { system_t sys_foo_t }; + +type file_t; +type file_exec_t, files; +type fs_t; +type base_optional_1; +type base_optional_2; + +allow sysadm_t file_exec_t: file { execute read write ioctl lock entrypoint }; + +optional { + require { + type base_optional_1, base_optional_2; + } + allow base_optional_1 base_optional_2 : file { read write }; +} + +##################################### +# Role Allow +allow user_r sysadm_r; + +#################################### +# Booleans +bool allow_ypbind true; +bool secure_mode false; +bool allow_execheap false; +bool allow_execmem true; +bool allow_execmod false; +bool allow_execstack true; +bool optional_bool_1 true; +bool optional_bool_2 false; + +##################################### +# users +gen_user(system_u,, system_r, s0, s0 - s0:c0.c23) +gen_user(root,, user_r sysadm_r, s0, s0 - s0:c0.c23) +gen_user(joe,, user_r, s0, s0 - s0:c0.c23) + +##################################### +# constraints + + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(system_u:system_r:sys_foo_t, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr ext3 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr reiserfs gen_context(system_u:object_r:fs_t, s0); + + +genfscon proc / gen_context(system_u:object_r:sys_foo_t, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 system_u:object_r:net_foo_t:s0 + +#netifcon lo system_u:object_r:net_foo_t system_u:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 system_u:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(system_u:object_r:net_foo_t, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-expander/alias-base.conf b/kernel/libsepol/tests/policies/test-expander/alias-base.conf new file mode 100644 index 00000000..b950039d --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/alias-base.conf @@ -0,0 +1,501 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +type enable_optional; + +# Alias tests +type alias_check_1_t; +type alias_check_2_t; +type alias_check_3_t; + +typealias alias_check_1_t alias alias_check_1_a; + +optional { + require { + type alias_check_2_t; + } + typealias alias_check_2_t alias alias_check_2_a; +} + +optional { + require { + type alias_check_3_a; + } + allow alias_check_3_a enable_optional:file read; +} + +######## +type fs_t; +type system_t; +type user_t; +role system_r; +role user_r; +role sysadm_r; +role system_r types system_t; +role user_r types user_t; +role sysadm_r types system_t; +#################################### +# Booleans +bool allow_ypbind true; +bool secure_mode false; +bool allow_execheap false; +bool allow_execmem true; +bool allow_execmod false; +bool allow_execstack true; +bool optional_bool_1 true; +bool optional_bool_2 false; + +##################################### +# users +gen_user(system_u,, system_r, s0, s0 - s0:c0.c23) +gen_user(root,, user_r sysadm_r, s0, s0 - s0:c0.c23) +gen_user(joe,, user_r, s0, s0 - s0:c0.c23) + +##################################### +# constraints + + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(system_u:system_r:system_t, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr ext3 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr reiserfs gen_context(system_u:object_r:fs_t, s0); + + +genfscon proc / gen_context(system_u:object_r:system_t, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 system_u:object_r:net_foo_t:s0 + +#netifcon lo system_u:object_r:net_foo_t system_u:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 system_u:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(system_u:object_r:system_t, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-expander/alias-module.conf b/kernel/libsepol/tests/policies/test-expander/alias-module.conf new file mode 100644 index 00000000..72d791e7 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/alias-module.conf @@ -0,0 +1,8 @@ +module my_module 1.0; + +require { + type alias_check_3_t; +} + +typealias alias_check_3_t alias alias_check_3_a; + diff --git a/kernel/libsepol/tests/policies/test-expander/base-base-only.conf b/kernel/libsepol/tests/policies/test-expander/base-base-only.conf new file mode 100644 index 00000000..4eae73ea --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/base-base-only.conf @@ -0,0 +1,44 @@ +class security +class file + +sid kernel + +common file +{ + read +} + +class file +inherits file +{ + entrypoint +} + +class security +{ + compute_av +} + +ifdef(`enable_mls',` +sensitivity s0; + +dominance { s0 } + +category c0; + +level s0:c0; + +mlsconstrain file { read } + ( h1 dom h2 ); +') + +attribute myattr; +type mytype_t; +role myrole_r; +role myrole_r types mytype_t; +bool mybool true; +gen_user(myuser_u,, myrole_r, s0, s0 - s0:c0) + +sid kernel gen_context(myuser_u:myrole_r:mytype_t, s0) + + diff --git a/kernel/libsepol/tests/policies/test-expander/module.conf b/kernel/libsepol/tests/policies/test-expander/module.conf new file mode 100644 index 00000000..6186db74 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/module.conf @@ -0,0 +1,228 @@ +module my_module 1.0; + +require { + bool allow_ypbind, secure_mode, allow_execstack; + type system_t, sysadm_t; + class file {read write}; + attribute attr_check_base_2, attr_check_base_3; + attribute attr_check_base_optional_2; +} + +bool module_1_bool true; + +if (module_1_bool && allow_ypbind && secure_mode && allow_execstack) { + allow system_t sysadm_t : file { read write }; +} + +optional { + bool module_1_bool_2 false; + require { + bool optional_bool_1, optional_bool_2; + class file { execute ioctl }; + } + if (optional_bool_1 && optional_bool_2 || module_1_bool_2) { + allow system_t sysadm_t : file {execute ioctl}; + } +} +# Type - attribute mapping test +type module_t; +attribute attr_check_mod_1; +attribute attr_check_mod_2; +attribute attr_check_mod_3; +attribute attr_check_mod_4; +attribute attr_check_mod_5; +attribute attr_check_mod_6; +attribute attr_check_mod_7; +attribute attr_check_mod_8; +attribute attr_check_mod_9; +attribute attr_check_mod_10; +attribute attr_check_mod_11; +optional { + require { + type base_t; + } + attribute attr_check_mod_optional_1; + attribute attr_check_mod_optional_2; + attribute attr_check_mod_optional_3; + attribute attr_check_mod_optional_4; + attribute attr_check_mod_optional_5; + attribute attr_check_mod_optional_6; + attribute attr_check_mod_optional_7; +} +optional { + require { + type does_not_exist_t; + } + attribute attr_check_mod_optional_disabled_4; + attribute attr_check_mod_optional_disabled_7; +} +type attr_check_base_2_1_t, attr_check_base_2; +type attr_check_base_2_2_t; +typeattribute attr_check_base_2_2_t attr_check_base_2; +type attr_check_base_3_3_t, attr_check_base_3; +type attr_check_base_3_4_t; +typeattribute attr_check_base_3_4_t attr_check_base_3; +optional { + require { + attribute attr_check_base_5; + } + type attr_check_base_5_1_t, attr_check_base_5; + type attr_check_base_5_2_t; + typeattribute attr_check_base_5_2_t attr_check_base_5; +} +optional { + require { + attribute attr_check_base_6; + } + type attr_check_base_6_3_t, attr_check_base_6; + type attr_check_base_6_4_t; + typeattribute attr_check_base_6_4_t attr_check_base_6; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_base_8; + } + type attr_check_base_8_1_t, attr_check_base_8; + type attr_check_base_8_2_t; + typeattribute attr_check_base_8_2_t attr_check_base_8; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_base_9; + } + type attr_check_base_9_3_t, attr_check_base_9; + type attr_check_base_9_4_t; + typeattribute attr_check_base_9_4_t attr_check_base_9; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_base_10; + } + type attr_check_base_10_3_t, attr_check_base_10; + type attr_check_base_10_4_t; + typeattribute attr_check_base_10_4_t attr_check_base_10; +} +optional { + require { + attribute attr_check_base_11; + } + type attr_check_base_11_3_t, attr_check_base_11; + type attr_check_base_11_4_t; + typeattribute attr_check_base_11_4_t attr_check_base_11; +} +type attr_check_base_optional_2_1_t, attr_check_base_optional_2; +type attr_check_base_optional_2_2_t; +typeattribute attr_check_base_optional_2_2_t attr_check_base_optional_2; +optional { + require { + attribute attr_check_base_optional_5; + } + type attr_check_base_optional_5_1_t, attr_check_base_optional_5; + type attr_check_base_optional_5_2_t; + typeattribute attr_check_base_optional_5_2_t attr_check_base_optional_5; +} +#optional { +# require { +# attribute attr_check_base_optional_6; +# } +# type attr_check_base_optional_6_3_t, attr_check_base_optional_6; +# type attr_check_base_optional_6_4_t; +# typeattribute attr_check_base_optional_6_4_t attr_check_base_optional_6; +#} +optional { + require { + type does_not_exist_t; + attribute attr_check_base_optional_8; + } + type attr_check_base_optional_8_1_t, attr_check_base_optional_8; + type attr_check_base_optional_8_2_t; + typeattribute attr_check_base_optional_8_2_t attr_check_base_optional_8; +} +type attr_check_mod_2_1_t, attr_check_mod_2; +type attr_check_mod_2_2_t; +typeattribute attr_check_mod_2_2_t attr_check_mod_2; +optional { + require { + attribute attr_check_mod_5; + } + type attr_check_mod_5_1_t, attr_check_mod_5; + type attr_check_mod_5_2_t; + typeattribute attr_check_mod_5_2_t attr_check_mod_5; +} +optional { + require { + attribute attr_check_mod_6; + } + type attr_check_mod_6_3_t, attr_check_mod_6; + type attr_check_mod_6_4_t; + typeattribute attr_check_mod_6_4_t attr_check_mod_6; +} +optional { + require { + type does_not_exist_t; + } + type attr_check_mod_8_1_t, attr_check_mod_8; + type attr_check_mod_8_2_t; + typeattribute attr_check_mod_8_2_t attr_check_mod_8; +} +optional { + require { + type does_not_exist_t; + } + type attr_check_mod_9_3_t, attr_check_mod_9; + type attr_check_mod_9_4_t; + typeattribute attr_check_mod_9_4_t attr_check_mod_9; +} +optional { + require { + type does_not_exist_t; + } + type attr_check_mod_10_3_t, attr_check_mod_10; + type attr_check_mod_10_4_t; + typeattribute attr_check_mod_10_4_t attr_check_mod_10; +} +optional { + require { + type base_t; + } + type attr_check_mod_11_3_t, attr_check_mod_11; + type attr_check_mod_11_4_t; + typeattribute attr_check_mod_11_4_t attr_check_mod_11; +} +#optional { +# require { +# attribute attr_check_mod_optional_5; +# } +# type attr_check_mod_optional_5_1_t, attr_check_mod_optional_5; +# type attr_check_mod_optional_5_2_t; +# typeattribute attr_check_mod_optional_5_2_t attr_check_mod_optional_5; +#} +#optional { +# require { +# attribute attr_check_mod_optional_6; +# } +# type attr_check_mod_optional_6_3_t, attr_check_mod_optional_6; +# type attr_check_mod_optional_6_4_t; +# typeattribute attr_check_mod_optional_6_4_t attr_check_mod_optional_6; +#} +optional { + require { + attribute attr_check_base_optional_disabled_5; + } + type attr_check_base_optional_disabled_5_1_t, attr_check_base_optional_disabled_5; + type attr_check_base_optional_disabled_5_2_t; + typeattribute attr_check_base_optional_disabled_5_2_t attr_check_base_optional_disabled_5; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_base_optional_disabled_8; + } + type attr_check_base_optional_disabled_8_1_t, attr_check_base_optional_disabled_8; + type attr_check_base_optional_disabled_8_2_t; + typeattribute attr_check_base_optional_disabled_8_2_t attr_check_base_optional_disabled_8; +} + diff --git a/kernel/libsepol/tests/policies/test-expander/role-base.conf b/kernel/libsepol/tests/policies/test-expander/role-base.conf new file mode 100644 index 00000000..8e88b4be --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/role-base.conf @@ -0,0 +1,483 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +# Role mapping test +type role_check_1_1_t; +role role_check_1; +role role_check_1 types role_check_1_1_t; + +######## +type fs_t; +type system_t; +type user_t; +role system_r; +role user_r; +role sysadm_r; +role system_r types system_t; +role user_r types user_t; +role sysadm_r types system_t; +#################################### +# Booleans +bool allow_ypbind true; +bool secure_mode false; +bool allow_execheap false; +bool allow_execmem true; +bool allow_execmod false; +bool allow_execstack true; +bool optional_bool_1 true; +bool optional_bool_2 false; + +##################################### +# users +gen_user(system_u,, system_r, s0, s0 - s0:c0.c23) +gen_user(root,, user_r sysadm_r, s0, s0 - s0:c0.c23) +gen_user(joe,, user_r, s0, s0 - s0:c0.c23) + +##################################### +# constraints + + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(system_u:system_r:system_t, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr ext3 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr reiserfs gen_context(system_u:object_r:fs_t, s0); + + +genfscon proc / gen_context(system_u:object_r:system_t, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 system_u:object_r:net_foo_t:s0 + +#netifcon lo system_u:object_r:net_foo_t system_u:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 system_u:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(system_u:object_r:system_t, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-expander/role-module.conf b/kernel/libsepol/tests/policies/test-expander/role-module.conf new file mode 100644 index 00000000..1cc5d225 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/role-module.conf @@ -0,0 +1,9 @@ +module my_module 1.0; + +require { + class file {read write}; + role role_check_1; +} + +type role_check_1_2_t; +role role_check_1 types role_check_1_2_t; diff --git a/kernel/libsepol/tests/policies/test-expander/small-base.conf b/kernel/libsepol/tests/policies/test-expander/small-base.conf new file mode 100644 index 00000000..055ea054 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/small-base.conf @@ -0,0 +1,721 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +#################################### +#################################### +##################################### +# TE RULES +attribute domain; +attribute system; +attribute foo; +attribute num; +attribute num_exec; +attribute files; + +# Type - attribute mapping test +# Shorthand tests +# 1 = types in base, 2 = types in mod, 3 = types in both +# 4 = types in optional in base, 5 = types in optional in mod +# 6 = types in optional in both +# 7 = types in disabled optional in base +# 8 = types in disabled optional in module +# 9 = types in disabled optional in both +# 10 = types in enabled optional in base, disabled optional in module +# 11 = types in disabled optional in base, enabled optional in module +attribute attr_check_base_1; +attribute attr_check_base_2; +attribute attr_check_base_3; +attribute attr_check_base_4; +attribute attr_check_base_5; +attribute attr_check_base_6; +attribute attr_check_base_7; +attribute attr_check_base_8; +attribute attr_check_base_9; +attribute attr_check_base_10; +attribute attr_check_base_11; +optional { + require { + type module_t; + } + attribute attr_check_base_optional_1; + attribute attr_check_base_optional_2; + attribute attr_check_base_optional_3; + attribute attr_check_base_optional_4; + attribute attr_check_base_optional_5; + attribute attr_check_base_optional_6; + attribute attr_check_base_optional_8; +} +optional { + require { + type does_not_exist_t; + } + attribute attr_check_base_optional_disabled_5; + attribute attr_check_base_optional_disabled_8; +} + +type net_foo_t, foo; +type sys_foo_t, foo, system; +role system_r; +role system_r types sys_foo_t; + +type user_t, domain; +role user_r; +role user_r types user_t; + +type sysadm_t, domain, system; +role sysadm_r; +role sysadm_r types sysadm_t; + +type system_t, domain, system, foo; +role system_r types { system_t sys_foo_t }; + +type file_t; +type file_exec_t, files; +type fs_t; +type base_optional_1; +type base_optional_2; + +allow sysadm_t file_exec_t: file { execute read write ioctl lock entrypoint }; + +optional { + require { + type base_optional_1, base_optional_2; + } + allow base_optional_1 base_optional_2 : file { read write }; +} + +# Type - attribute mapping test +type base_t; +type attr_check_base_1_1_t, attr_check_base_1; +type attr_check_base_1_2_t; +typeattribute attr_check_base_1_2_t attr_check_base_1; +type attr_check_base_3_1_t, attr_check_base_3; +type attr_check_base_3_2_t; +typeattribute attr_check_base_3_2_t attr_check_base_3; +optional { + require { + attribute attr_check_base_4; + } + type attr_check_base_4_1_t, attr_check_base_4; + type attr_check_base_4_2_t; + typeattribute attr_check_base_4_2_t attr_check_base_4; +} +optional { + require { + type module_t; + } + type attr_check_base_6_1_t, attr_check_base_6; + type attr_check_base_6_2_t; + typeattribute attr_check_base_6_2_t attr_check_base_6; +} +optional { + require { + type does_not_exist_t; + } + type attr_check_base_7_1_t, attr_check_base_7; + type attr_check_base_7_2_t; + typeattribute attr_check_base_7_2_t attr_check_base_7; +} +optional { + require { + type does_not_exist_t; + } + type attr_check_base_9_1_t, attr_check_base_9; + type attr_check_base_9_2_t; + typeattribute attr_check_base_9_2_t attr_check_base_9; +} +optional { + require { + type module_t; + } + type attr_check_base_10_1_t, attr_check_base_10; + type attr_check_base_10_2_t; + typeattribute attr_check_base_10_2_t attr_check_base_10; +} +optional { + require { + type does_not_exist_t; + } + type attr_check_base_11_1_t, attr_check_base_11; + type attr_check_base_11_2_t; + typeattribute attr_check_base_11_2_t attr_check_base_11; +} +#optional { +# require { +# attribute attr_check_base_optional_4; +# } +# type attr_check_base_optional_4_1_t, attr_check_base_optional_4; +# type attr_check_base_optional_4_2_t; +# typeattribute attr_check_base_optional_4_2_t attr_check_base_optional_4; +#} +#optional { +# require { +# attribute attr_check_base_optional_6; +# } +# type attr_check_base_optional_6_1_t, attr_check_base_optional_6; +# type attr_check_base_optional_6_2_t; +# typeattribute attr_check_base_optional_6_2_t attr_check_base_optional_6; +#} +optional { + require { + attribute attr_check_mod_4; + } + type attr_check_mod_4_1_t, attr_check_mod_4; + type attr_check_mod_4_2_t; + typeattribute attr_check_mod_4_2_t attr_check_mod_4; +} +optional { + require { + attribute attr_check_mod_6; + } + type attr_check_mod_6_1_t, attr_check_mod_6; + type attr_check_mod_6_2_t; + typeattribute attr_check_mod_6_2_t attr_check_mod_6; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_mod_7; + } + type attr_check_mod_7_1_t, attr_check_mod_7; + type attr_check_mod_7_2_t; + typeattribute attr_check_mod_7_2_t attr_check_mod_7; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_mod_9; + } + type attr_check_mod_9_1_t, attr_check_mod_9; + type attr_check_mod_9_2_t; + typeattribute attr_check_mod_9_2_t attr_check_mod_9; +} +optional { + require { + attribute attr_check_mod_10; + } + type attr_check_mod_10_1_t, attr_check_mod_10; + type attr_check_mod_10_2_t; + typeattribute attr_check_mod_10_2_t attr_check_mod_10; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_mod_11; + } + type attr_check_mod_11_1_t, attr_check_mod_11; + type attr_check_mod_11_2_t; + typeattribute attr_check_mod_11_2_t attr_check_mod_11; +} +optional { + require { + attribute attr_check_mod_optional_4; + } + type attr_check_mod_optional_4_1_t, attr_check_mod_optional_4; + type attr_check_mod_optional_4_2_t; + typeattribute attr_check_mod_optional_4_2_t attr_check_mod_optional_4; +} +optional { + require { + attribute attr_check_mod_optional_6; + } + type attr_check_mod_optional_6_1_t, attr_check_mod_optional_6; + type attr_check_mod_optional_6_2_t; + typeattribute attr_check_mod_optional_6_2_t attr_check_mod_optional_6; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_mod_optional_7; + } + type attr_check_mod_optional_7_1_t, attr_check_mod_optional_7; + type attr_check_mod_optional_7_2_t; + typeattribute attr_check_mod_optional_7_2_t attr_check_mod_optional_7; +} +optional { + require { + attribute attr_check_mod_optional_disabled_4; + } + type attr_check_mod_optional_disabled_4_1_t, attr_check_mod_optional_disabled_4; + type attr_check_mod_optional_disabled_4_2_t; + typeattribute attr_check_mod_optional_disabled_4_2_t attr_check_mod_optional_disabled_4; +} +optional { + require { + type does_not_exist_t; + attribute attr_check_mod_optional_disabled_7; + } + type attr_check_mod_optional_disabled_7_1_t, attr_check_mod_optional_disabled_7; + type attr_check_mod_optional_disabled_7_2_t; + typeattribute attr_check_mod_optional_disabled_7_2_t attr_check_mod_optional_disabled_7; +} + +##################################### +# Role Allow +allow user_r sysadm_r; + +#################################### +# Booleans +bool allow_ypbind true; +bool secure_mode false; +bool allow_execheap false; +bool allow_execmem true; +bool allow_execmod false; +bool allow_execstack true; +bool optional_bool_1 true; +bool optional_bool_2 false; + +##################################### +# users +gen_user(system_u,, system_r, s0, s0 - s0:c0.c23) +gen_user(root,, user_r sysadm_r, s0, s0 - s0:c0.c23) +gen_user(joe,, user_r, s0, s0 - s0:c0.c23) + +##################################### +# constraints + + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(system_u:system_r:sys_foo_t, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr ext3 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr reiserfs gen_context(system_u:object_r:fs_t, s0); + + +genfscon proc / gen_context(system_u:object_r:sys_foo_t, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 system_u:object_r:net_foo_t:s0 + +#netifcon lo system_u:object_r:net_foo_t system_u:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 system_u:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(system_u:object_r:net_foo_t, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-expander/user-base.conf b/kernel/libsepol/tests/policies/test-expander/user-base.conf new file mode 100644 index 00000000..b31ee8cd --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/user-base.conf @@ -0,0 +1,487 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +# User mapping test +type user_check_1_1_t; +type user_check_1_2_t; +role user_check_1_1_r; +role user_check_1_2_r; +role user_check_1_1_r types user_check_1_1_t; +role user_check_1_2_r types user_check_1_2_t; + +######## +type fs_t; +type system_t; +type user_t; +role system_r; +role user_r; +role sysadm_r; +role system_r types system_t; +role user_r types user_t; +role sysadm_r types system_t; +#################################### +# Booleans +bool allow_ypbind true; +bool secure_mode false; +bool allow_execheap false; +bool allow_execmem true; +bool allow_execmod false; +bool allow_execstack true; +bool optional_bool_1 true; +bool optional_bool_2 false; + +##################################### +# users +gen_user(user_check_1,, user_check_1_1_r user_check_1_2_r, s0, s0 - s0:c0.c23) +gen_user(system_u,, system_r, s0, s0 - s0:c0.c23) +gen_user(root,, user_r sysadm_r, s0, s0 - s0:c0.c23) +gen_user(joe,, user_r, s0, s0 - s0:c0.c23) + +##################################### +# constraints + + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(system_u:system_r:system_t, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr ext3 gen_context(system_u:object_r:fs_t, s0); +fs_use_xattr reiserfs gen_context(system_u:object_r:fs_t, s0); + + +genfscon proc / gen_context(system_u:object_r:system_t, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 system_u:object_r:net_foo_t:s0 + +#netifcon lo system_u:object_r:net_foo_t system_u:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 system_u:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(system_u:object_r:system_t, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-expander/user-module.conf b/kernel/libsepol/tests/policies/test-expander/user-module.conf new file mode 100644 index 00000000..4ef3e629 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-expander/user-module.conf @@ -0,0 +1,9 @@ +module my_module 1.0; + +require { + class file {read write}; +ifdef(`enable_mls',` + user user_check_1; +') +} + diff --git a/kernel/libsepol/tests/policies/test-hooks/cmp_policy.conf b/kernel/libsepol/tests/policies/test-hooks/cmp_policy.conf new file mode 100644 index 00000000..9082b333 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-hooks/cmp_policy.conf @@ -0,0 +1,471 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +#################################### +#################################### +##################################### + +#g_b stands for global base + +type g_b_type_1; +role g_b_role_1 types g_b_type_1; + +role g_b_role_2 types g_b_type_1; +role g_b_role_3 types g_b_type_1; +type g_b_type_2; + +optional { + require { + type invalid_type; + } + allow g_b_role_2 g_b_role_3; + role_transition g_b_role_2 g_b_type_2 g_b_role_3; +} + + +gen_user(g_b_user_1,, g_b_role_1, s0, s0 - s0:c0.c23) + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(g_b_user_1:g_b_role_1:g_b_type_1, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(g_b_user_1:object_r:g_b_type_1, s0); +fs_use_xattr ext3 gen_context(g_b_user_1:object_r:g_b_type_1, s0); +fs_use_xattr reiserfs gen_context(g_b_user_1:object_r:g_b_type_1, s0); + + +genfscon proc / gen_context(g_b_user_1:object_r:g_b_type_1, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 g_b_user_1:object_r:net_foo_t:s0 + +#netifcon lo g_b_user_1:object_r:net_foo_t g_b_user_1:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 g_b_user_1:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(g_b_user_1:object_r:g_b_type_1, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-hooks/module_add_role_allow_trans.conf b/kernel/libsepol/tests/policies/test-hooks/module_add_role_allow_trans.conf new file mode 100644 index 00000000..c6ecd838 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-hooks/module_add_role_allow_trans.conf @@ -0,0 +1,15 @@ +module add_symbol_test 1.0; + +require { class file { read }; } + +role role_a_1; +role role_a_2; +role role_t_1; +role role_t_2; + +type type_rt_1; + + +allow role_a_1 role_a_2; + +role_transition role_t_1 type_rt_1 role_t_2; diff --git a/kernel/libsepol/tests/policies/test-hooks/module_add_symbols.conf b/kernel/libsepol/tests/policies/test-hooks/module_add_symbols.conf new file mode 100644 index 00000000..cf56e183 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-hooks/module_add_symbols.conf @@ -0,0 +1,12 @@ +module add_symbol_test 1.0; + +require { class file { read write }; } + +type type_add_1; +attribute attrib_add_1; +role role_add_1; +bool bool_add_1 false; + +ifdef(`enable_mls',`',` +user user_add_1 roles { role_add_1 }; +') diff --git a/kernel/libsepol/tests/policies/test-hooks/small-base.conf b/kernel/libsepol/tests/policies/test-hooks/small-base.conf new file mode 100644 index 00000000..9082b333 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-hooks/small-base.conf @@ -0,0 +1,471 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +#################################### +#################################### +##################################### + +#g_b stands for global base + +type g_b_type_1; +role g_b_role_1 types g_b_type_1; + +role g_b_role_2 types g_b_type_1; +role g_b_role_3 types g_b_type_1; +type g_b_type_2; + +optional { + require { + type invalid_type; + } + allow g_b_role_2 g_b_role_3; + role_transition g_b_role_2 g_b_type_2 g_b_role_3; +} + + +gen_user(g_b_user_1,, g_b_role_1, s0, s0 - s0:c0.c23) + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(g_b_user_1:g_b_role_1:g_b_type_1, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(g_b_user_1:object_r:g_b_type_1, s0); +fs_use_xattr ext3 gen_context(g_b_user_1:object_r:g_b_type_1, s0); +fs_use_xattr reiserfs gen_context(g_b_user_1:object_r:g_b_type_1, s0); + + +genfscon proc / gen_context(g_b_user_1:object_r:g_b_type_1, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 g_b_user_1:object_r:net_foo_t:s0 + +#netifcon lo g_b_user_1:object_r:net_foo_t g_b_user_1:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 g_b_user_1:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(g_b_user_1:object_r:g_b_type_1, s0) + + + + diff --git a/kernel/libsepol/tests/policies/test-linker/module1.conf b/kernel/libsepol/tests/policies/test-linker/module1.conf new file mode 100644 index 00000000..2d5fc313 --- /dev/null +++ b/kernel/libsepol/tests/policies/test-linker/module1.conf @@ -0,0 +1,145 @@ +module linker_test_1 1.0; + +require { + class file { read write }; + class lnk_file append; + role g_b_role_2; + attribute g_b_attr_3; + attribute g_b_attr_5; + attribute o4_b_attr_1; + type g_b_type_3; +} + +type tag_g_m1; + +#test for type in module and attr in module, added to in module +attribute g_m1_attr_1; +type g_m1_type_1, g_m1_attr_1; +type g_m1_type_2; +typeattribute g_m1_type_2 g_m1_attr_1; + +#add role in module test +role g_m1_role_1; +role g_m1_role_1 types g_m1_type_1; + +# test for attr declared in base, added to in module +type g_m1_type_3; +typeattribute g_m1_type_3 g_b_attr_3; + +# test for attr declared in base, added to in 2 modules +type g_m1_type_4; +typeattribute g_m1_type_4 g_b_attr_5; + +# test for attr declared in base optional, added to in module +type g_m1_type_5; +typeattribute g_m1_type_5 o4_b_attr_1; + +# test for attr declared in module, added to in base optional +attribute g_m1_attr_2; + +#add type to base role test +role g_b_role_2 types g_m1_type_1; +role g_b_role_3; +role g_b_role_3 types g_m1_type_2; + +#add type to base optional role test +role o1_b_role_2; +role o1_b_role_2 types g_m1_type_1; + +#optional base role w/ adds in 2 modules +role o4_b_role_1; +role o4_b_role_1 types g_m1_type_2; + +# attr a added to in base optional, declared/added to in module, added to in other module +attribute g_m1_attr_3; +type g_m1_type_6, g_m1_attr_3; + +# attr a added to in base optional, declared/added in module , added to in other module optional +attribute g_m1_attr_4; +type g_m1_type_7, g_m1_attr_4; + +# alias tests +typealias g_b_type_3 alias g_m_alias_1; + +# single boolean in module +bool g_m1_bool_1 true; +if (g_m1_bool_1) { + allow g_m1_type_1 g_m1_type_2 : lnk_file append; +} + + +optional { + require { + type optional_type; + attribute g_b_attr_4; + attribute o1_b_attr_2; + class lnk_file { ioctl }; + } + + type tag_o1_m1; + + attribute o1_m1_attr_1; + type o1_m1_type_2, o1_m1_attr_1; + + type o1_m1_type_1; + role o1_m1_role_1; + role o1_m1_role_1 types o1_m1_type_1; + + type o1_m1_type_3; + typeattribute o1_m1_type_3 g_b_attr_4; + + type o1_m1_type_5; + typeattribute o1_m1_type_5 o1_b_attr_2; + + bool o1_m1_bool_1 false; + if (o1_m1_bool_1) { + allow o1_m1_type_2 o1_m1_type_1 : lnk_file ioctl; + } + +} + +optional { + require { + type optional_type; + #role g_b_role_4; // This causes a bug where the role scope doesn't get copied into base + } + + type tag_o2_m1; + + role g_b_role_4; + role g_b_role_4 types g_m1_type_2; +} + +optional { + require { + attribute g_b_attr_6; + } + + type tag_o3_m1; + + type o3_m1_type_1; + role o3_b_role_1; + role o3_b_role_1 types o3_m1_type_1; + + type o3_m1_type_2, g_b_attr_6; + + attribute o3_m1_attr_1; + + # attr a added to in base optional, declared/added in module optional, added to in other module + attribute o3_m1_attr_2; + type o3_m1_type_3, o3_m1_attr_2; + +} + +optional { + require { + type enable_optional; + } + type tag_o4_m1; + + attribute o4_m1_attr_1; + type o4_m1_type_1; + typeattribute o4_m1_type_1 o4_m1_attr_1; + + +} diff --git a/kernel/libsepol/tests/policies/test-linker/module2.conf b/kernel/libsepol/tests/policies/test-linker/module2.conf new file mode 100644 index 00000000..7a31109b --- /dev/null +++ b/kernel/libsepol/tests/policies/test-linker/module2.conf @@ -0,0 +1,66 @@ +module linker_test_2 1.0; + +require { + class file { read write }; + class lnk_file { unlink }; + attribute g_b_attr_5; + attribute g_b_attr_6; + attribute g_m1_attr_3; + attribute o3_m1_attr_2; +} + +type tag_g_m2; + +type g_m2_type_1; +role g_m2_role_1; +role g_m2_role_1 types g_m2_type_1; + +type g_m2_type_4, g_b_attr_5; +type g_m2_type_5, g_b_attr_6; + +#add types to role declared in base test +type g_m2_type_2; +role g_b_role_3; +role g_b_role_3 types g_m2_type_2; + +#optional base role w/ adds in 2 modules +role o4_b_role_1; +role o4_b_role_1 types g_m2_type_1; + +# attr a added to in base optional, declared/added to in module, added to in other module +type g_m2_type_3, g_m1_attr_3; + +# attr a added to in base optional, declared/added in module optional, added to in other module +type g_m2_type_6, o3_m1_attr_2; + +# cond mapping tests +bool g_m2_bool_1 true; +bool g_m2_bool_2 false; +if (g_m2_bool_1 && g_m2_bool_2) { + allow g_m2_type_1 g_m2_type_2 : lnk_file unlink; +} + +optional { + require { + type optional_type; + } + + type tag_o1_m2; + + type o1_m2_type_1; + role o1_m2_role_1; + role o1_m2_role_1 types o1_m2_type_1; +} + + +optional { + require { + attribute g_m1_attr_4; + attribute o4_m1_attr_1; + } + type tag_o2_m2; + + type o2_m2_type_1, g_m1_attr_4; + type o2_m2_type_2, o4_m1_attr_1; + +} diff --git a/kernel/libsepol/tests/policies/test-linker/small-base.conf b/kernel/libsepol/tests/policies/test-linker/small-base.conf new file mode 100644 index 00000000..890ebbeb --- /dev/null +++ b/kernel/libsepol/tests/policies/test-linker/small-base.conf @@ -0,0 +1,600 @@ +# FLASK + +# +# Define the security object classes +# + +class security +class process +class system +class capability + +# file-related classes +class filesystem +class file +class dir +class fd +class lnk_file +class chr_file +class blk_file +class sock_file +class fifo_file + +# network-related classes +class socket +class tcp_socket +class udp_socket +class rawip_socket +class node +class netif +class netlink_socket +class packet_socket +class key_socket +class unix_stream_socket +class unix_dgram_socket + +# sysv-ipc-related clases +class sem +class msg +class msgq +class shm +class ipc + +# FLASK +# FLASK + +# +# Define initial security identifiers +# + +sid kernel + + +# FLASK +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + + +# +# Define a common prefix for file access vectors. +# + +common file +{ + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append + unlink + link + rename + execute + swapon + quotaon + mounton +} + + +# +# Define a common prefix for socket access vectors. +# + +common socket +{ +# inherited from file + ioctl + read + write + create + getattr + setattr + lock + relabelfrom + relabelto + append +# socket-specific + bind + connect + listen + accept + getopt + setopt + shutdown + recvfrom + sendto + recv_msg + send_msg + name_bind +} + +# +# Define a common prefix for ipc access vectors. +# + +common ipc +{ + create + destroy + getattr + setattr + read + write + associate + unix_read + unix_write +} + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class filesystem +{ + mount + remount + unmount + getattr + relabelfrom + relabelto + transition + associate + quotamod + quotaget +} + +class dir +inherits file +{ + add_name + remove_name + reparent + search + rmdir +} + +class file +inherits file +{ + execute_no_trans + entrypoint +} + +class lnk_file +inherits file + +class chr_file +inherits file + +class blk_file +inherits file + +class sock_file +inherits file + +class fifo_file +inherits file + +class fd +{ + use +} + + +# +# Define the access vector interpretation for network-related objects. +# + +class socket +inherits socket + +class tcp_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class udp_socket +inherits socket + +class rawip_socket +inherits socket + +class node +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send + enforce_dest +} + +class netif +{ + tcp_recv + tcp_send + udp_recv + udp_send + rawip_recv + rawip_send +} + +class netlink_socket +inherits socket + +class packet_socket +inherits socket + +class key_socket +inherits socket + +class unix_stream_socket +inherits socket +{ + connectto + newconn + acceptfrom +} + +class unix_dgram_socket +inherits socket + + +# +# Define the access vector interpretation for process-related objects +# + +class process +{ + fork + transition + sigchld # commonly granted from child to parent + sigkill # cannot be caught or ignored + sigstop # cannot be caught or ignored + signull # for kill(pid, 0) + signal # all other signals + ptrace + getsched + setsched + getsession + getpgid + setpgid + getcap + setcap + share +} + + +# +# Define the access vector interpretation for ipc-related objects +# + +class ipc +inherits ipc + +class sem +inherits ipc + +class msgq +inherits ipc +{ + enqueue +} + +class msg +{ + send + receive +} + +class shm +inherits ipc +{ + lock +} + + +# +# Define the access vector interpretation for the security server. +# + +class security +{ + compute_av + transition_sid + member_sid + sid_to_context + context_to_sid + load_policy + get_sids + change_sid + get_user_sids +} + + +# +# Define the access vector interpretation for system operations. +# + +class system +{ + ipc_info + avc_toggle + nfsd_control + bdflush + syslog_read + syslog_mod + syslog_console + ichsid +} + +# +# Define the access vector interpretation for controlling capabilities +# + +class capability +{ + # The capabilities are defined in include/linux/capability.h + # Care should be taken to ensure that these are consistent with + # those definitions. (Order matters) + + chown + dac_override + dac_read_search + fowner + fsetid + kill + setgid + setuid + setpcap + linux_immutable + net_bind_service + net_broadcast + net_admin + net_raw + ipc_lock + ipc_owner + sys_module + sys_rawio + sys_chroot + sys_ptrace + sys_pacct + sys_admin + sys_boot + sys_nice + sys_resource + sys_time + sys_tty_config + mknod + lease +} + +ifdef(`enable_mls',` +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write setattr append unlink link rename ioctl lock execute relabelfrom } + ( h1 dom h2 ); +') + +#################################### +#################################### +##################################### + +#g_b stands for global base + +type enable_optional; + +#decorative type for finding this decl, every block should have one +type tag_g_b; + +attribute g_b_attr_1; +attribute g_b_attr_2; +attribute g_b_attr_3; +attribute g_b_attr_4; +attribute g_b_attr_5; +attribute g_b_attr_6; + +type g_b_type_1, g_b_attr_1; +type g_b_type_2, g_b_attr_2; +type g_b_type_3; + +role g_b_role_1; +role g_b_role_2; +role g_b_role_3; +role g_b_role_4; +role g_b_role_1 types g_b_type_1; +role g_b_role_2 types g_b_type_2; +role g_b_role_3 types g_b_type_2; +role g_b_role_4 types g_b_type_2; + +bool g_b_bool_1 false; +bool g_b_bool_2 true; + +allow g_b_type_1 g_b_type_2 : security { compute_av load_policy }; +allow g_b_type_1 g_b_type_2 : file *; # test * +allow g_b_type_1 g_b_type_2 : process ~ptrace; #test ~ + +typealias g_b_type_3 alias g_b_alias_1; + +if (g_b_bool_1) { + allow g_b_type_1 g_b_type_2: lnk_file read; +} + + +optional { + require { + type enable_optional; + attribute g_m1_attr_2; + } + type tag_o1_b; + + attribute o1_b_attr_1; + type o1_b_type_1, o1_b_attr_1; + bool o1_b_bool_1 true; + role o1_b_role_1; + role o1_b_role_1 types o1_b_type_1; + role o1_b_role_2; + role o1_b_role_2 types o1_b_type_1; + + attribute o1_b_attr_2; + + type o1_b_type_2, g_m1_attr_2; + + if (o1_b_bool_1) { + allow o1_b_type_1 o1_b_type_2: lnk_file write; + } + +} + +optional { + require { + # this should be activated by module 1 + type g_m1_type_1; + attribute o3_m1_attr_2; + } + type tag_o2_b; + + type o2_b_type_1, o3_m1_attr_2; +} + +optional { + require { + #this block should not come on + type invalid_type; + } + type tag_o3_b; + + + attribute o3_b_attr_1; + type o3_b_type_1; + bool o3_b_bool_1 true; + + role o3_b_role_1; + role o3_b_role_1 types o3_b_type_1; + + allow g_b_type_1 invalid_type : sem { create destroy }; +} + +optional { + require { + # also should be enabled by module 1 + type enable_optional; + type g_m1_type_1; + attribute o3_m1_attr_1; + attribute g_m1_attr_3; + } + + type tag_o4_b; + + attribute o4_b_attr_1; + + role o4_b_role_1; + role o4_b_role_1 types g_m1_type_1; + + # test for attr declared in module optional, added to in base optional + type o4_b_type_1, o3_m1_attr_1; + + type o4_b_type_2, g_m1_attr_3; +} + +optional { + require { + attribute g_m1_attr_4; + attribute o4_m1_attr_1; + } + type tag_o5_b; + + type o5_b_type_1, g_m1_attr_4; + type o5_b_type_2, o4_m1_attr_1; +} + +optional { + require { + type enable_optional; + } + type tag_o6_b; + + typealias g_b_type_3 alias g_b_alias_2; +} + +optional { + require { + type g_m_alias_1; + } + type tag_o7_b; + + allow g_m_alias_1 enable_optional:file read; +} + +gen_user(g_b_user_1,, g_b_role_1, s0, s0 - s0:c0.c23) +gen_user(g_b_user_2,, g_b_role_1, s0, s0 - s0:c0, c1, c3, c4, c5) + +#################################### +#line 1 "initial_sid_contexts" + +sid kernel gen_context(g_b_user_1:g_b_role_1:g_b_type_1, s0) + + +############################################ +#line 1 "fs_use" +# +fs_use_xattr ext2 gen_context(g_b_user_1:object_r:g_b_type_1, s0); +fs_use_xattr ext3 gen_context(g_b_user_1:object_r:g_b_type_1, s0); +fs_use_xattr reiserfs gen_context(g_b_user_1:object_r:g_b_type_1, s0); + + +genfscon proc / gen_context(g_b_user_1:object_r:g_b_type_1, s0) + + +#################################### +#line 1 "net_contexts" + +#portcon tcp 21 g_b_user_1:object_r:net_foo_t:s0 + +#netifcon lo g_b_user_1:object_r:net_foo_t g_b_user_1:object_r:net_foo_t:s0 + +# +#nodecon 127.0.0.1 255.255.255.255 g_b_user_1:object_r:net_foo_t:s0 + +nodecon ::1 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF gen_context(g_b_user_1:object_r:g_b_type_1, s0) + + + + diff --git a/kernel/libsepol/tests/test-common.c b/kernel/libsepol/tests/test-common.c new file mode 100644 index 00000000..52117853 --- /dev/null +++ b/kernel/libsepol/tests/test-common.c @@ -0,0 +1,265 @@ +/* + * Author: Joshua Brindle + * Chad Sellers + * Chris PeBenito + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This has tests that are common between test suites*/ + +#include + +#include + +#include "test-common.h" +#include "helpers.h" + +void test_sym_presence(policydb_t * p, const char *id, int sym_type, unsigned int scope_type, unsigned int *decls, unsigned int len) +{ + scope_datum_t *scope; + int found; + unsigned int i, j; + /* make sure it is in global symtab */ + if (!hashtab_search(p->symtab[sym_type].table, id)) { + fprintf(stderr, "symbol %s not found in table %d\n", id, sym_type); + CU_FAIL_FATAL(); + } + /* make sure its scope is correct */ + scope = hashtab_search(p->scope[sym_type].table, id); + CU_ASSERT_FATAL(scope != NULL); + CU_ASSERT(scope->scope == scope_type); + CU_ASSERT(scope->decl_ids_len == len); + if (scope->decl_ids_len != len) + fprintf(stderr, "sym %s has %d decls, %d expected\n", id, scope->decl_ids_len, len); + for (i = 0; i < len; i++) { + found = 0; + for (j = 0; j < len; j++) { + if (decls[i] == scope->decl_ids[j]) + found++; + } + CU_ASSERT(found == 1); + } + +} + +static int common_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + common_datum_t *d = (common_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + CU_ASSERT(p->sym_val_to_name[SYM_COMMONS][d->s.value - 1] == (char *)key); + return 0; +} + +static int class_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + class_datum_t *d = (class_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + CU_ASSERT(p->sym_val_to_name[SYM_CLASSES][d->s.value - 1] == (char *)key); + CU_ASSERT(p->class_val_to_struct[d->s.value - 1] == d); + return 0; +} + +static int role_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + role_datum_t *d = (role_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + CU_ASSERT(p->sym_val_to_name[SYM_ROLES][d->s.value - 1] == (char *)key); + CU_ASSERT(p->role_val_to_struct[d->s.value - 1] == d); + return 0; +} + +static int type_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + type_datum_t *d = (type_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + if (!d->primary) + return 0; + + CU_ASSERT(p->sym_val_to_name[SYM_TYPES][d->s.value - 1] == (char *)key); + CU_ASSERT(p->type_val_to_struct[d->s.value - 1] == d); + + return 0; +} + +static int user_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + user_datum_t *d = (user_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + CU_ASSERT(p->sym_val_to_name[SYM_USERS][d->s.value - 1] == (char *)key); + CU_ASSERT(p->user_val_to_struct[d->s.value - 1] == d); + return 0; +} + +static int cond_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + cond_bool_datum_t *d = (cond_bool_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + CU_ASSERT(p->sym_val_to_name[SYM_BOOLS][d->s.value - 1] == (char *)key); + CU_ASSERT(p->bool_val_to_struct[d->s.value - 1] == d); + return 0; +} + +static int level_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + level_datum_t *d = (level_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + CU_ASSERT(p->sym_val_to_name[SYM_LEVELS][d->level->sens - 1] == (char *)key); + return 0; +} + +static int cat_test_index(hashtab_key_t key, hashtab_datum_t datum, void *data) +{ + cat_datum_t *d = (cat_datum_t *) datum; + policydb_t *p = (policydb_t *) data; + + CU_ASSERT(p->sym_val_to_name[SYM_CATS][d->s.value - 1] == (char *)key); + return 0; +} + +static int (*test_index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, void *p) = { +common_test_index, class_test_index, role_test_index, type_test_index, user_test_index, cond_test_index, level_test_index, cat_test_index,}; + +void test_policydb_indexes(policydb_t * p) +{ + int i; + + for (i = 0; i < SYM_NUM; i++) { + ksu_hashtab_map(p->symtab[i].table, test_index_f[i], p); + } +} + +void test_alias_datum(policydb_t * p, const char *id, const char *primary_id, char mode, unsigned int flavor) +{ + type_datum_t *type, *primary; + unsigned int my_primary, my_flavor, my_value; + + type = hashtab_search(p->p_types.table, id); + primary = hashtab_search(p->p_types.table, primary_id); + + CU_ASSERT_PTR_NOT_NULL(type); + CU_ASSERT_PTR_NOT_NULL(primary); + + if (type && primary) { + if (mode) { + my_flavor = type->flavor; + } else { + my_flavor = flavor; + } + + if (my_flavor == TYPE_TYPE) { + my_primary = 0; + my_value = primary->s.value; + } else { + CU_ASSERT(my_flavor == TYPE_ALIAS); + my_primary = primary->s.value; + CU_ASSERT_NOT_EQUAL(type->s.value, primary->s.value); + my_value = type->s.value; + } + + CU_ASSERT(type->primary == my_primary); + CU_ASSERT(type->flavor == my_flavor); + CU_ASSERT(type->s.value == my_value); + } +} + +role_datum_t *test_role_type_set(policydb_t * p, const char *id, avrule_decl_t * decl, const char **types, unsigned int len, unsigned int flags) +{ + ebitmap_node_t *tnode; + unsigned int i, j, new, found = 0; + role_datum_t *role; + + if (decl) + role = hashtab_search(decl->p_roles.table, id); + else + role = hashtab_search(p->p_roles.table, id); + + if (!role) + printf("role %s can't be found! \n", id); + + CU_ASSERT_FATAL(role != NULL); + + ebitmap_for_each_positive_bit(&role->types.types, tnode, i) { + new = 0; + for (j = 0; j < len; j++) { + if (strcmp(p->sym_val_to_name[SYM_TYPES][i], types[j]) == 0) { + found++; + new = 1; + } + } + if (new == 0) { + printf("\nRole %s had type %s not in types array\n", + id, p->sym_val_to_name[SYM_TYPES][i]); + } + CU_ASSERT(new == 1); + } + CU_ASSERT(found == len); + if (found != len) + printf("\nrole %s has %d types, %d expected\n", p->sym_val_to_name[SYM_ROLES][role->s.value - 1], found, len); + /* roles should never have anything in the negset */ + CU_ASSERT(role->types.negset.highbit == 0); + CU_ASSERT(role->types.flags == flags); + + return role; +} + +void test_attr_types(policydb_t * p, const char *id, avrule_decl_t * decl, const char **types, int len) +{ + ebitmap_node_t *tnode; + int j, new, found = 0; + unsigned int i; + type_datum_t *attr; + + if (decl) { + attr = hashtab_search(decl->p_types.table, id); + if (attr == NULL) + printf("could not find attr %s in decl %d\n", id, decl->decl_id); + } else { + attr = hashtab_search(p->p_types.table, id); + if (attr == NULL) + printf("could not find attr %s in policy\n", id); + } + + CU_ASSERT_FATAL(attr != NULL); + CU_ASSERT(attr->flavor == TYPE_ATTRIB); + CU_ASSERT(attr->primary == 1); + + ebitmap_for_each_positive_bit(&attr->types, tnode, i) { + new = 0; + for (j = 0; j < len; j++) { + if (strcmp(p->sym_val_to_name[SYM_TYPES][i], types[j]) == 0) { + found++; + new = 1; + } + } + if (new == 0) { + printf("\nattr %s had type %s not in types array\n", + id, p->sym_val_to_name[SYM_TYPES][i]); + } + CU_ASSERT(new == 1); + } + CU_ASSERT(found == len); + if (found != len) + printf("\nattr %s has %d types, %d expected\n", id, found, len); +} diff --git a/kernel/libsepol/tests/test-common.h b/kernel/libsepol/tests/test-common.h new file mode 100644 index 00000000..1e31c8d1 --- /dev/null +++ b/kernel/libsepol/tests/test-common.h @@ -0,0 +1,78 @@ +/* + * Author: Joshua Brindle + * Chad Sellers + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_COMMON_H__ +#define __TEST_COMMON_H__ + +#include + +/* p the policy being inspected + * id string symbol identifier + * sym_type symbol type (eg., SYM_ROLES, SYM_TYPES) + * scope_type what scope the role should have (eg., SCOPE_DECL or SCOPE_REQ) + * decls integer array of decl id's that we expect the role to have in the scope table + * len number of elements in decls + * + * This is a utility function to test for the symbol's presence in the global symbol table, + * the scope table, and that the decl blocks we think this symbol is in are correct + */ +extern void test_sym_presence(policydb_t * p, const char *id, int sym_type, unsigned int scope_type, unsigned int *decls, unsigned int len); + +/* Test the indexes in the policydb to ensure their correctness. These include + * the sym_val_to_name[], class_val_to_struct, role_val_to_struct, type_val_to_struct, + * user_val_to_struct, and bool_val_to_struct indexes. + */ +extern void test_policydb_indexes(policydb_t * p); + +/* Test alias datum to ensure that it is as expected + * + * id = the key for the alias + * primary_id = the key for its primary + * mode: 0 = test the datum according to the flavor value in the call + 1 = automatically detect the flavor value and test the datum accordingly + * flavor = flavor value if in mode 0 + */ +extern void test_alias_datum(policydb_t * p, const char *id, const char *primary_id, char mode, unsigned int flavor); + +/* p the policy being inspected + * id string role identifier + * decl the decl block which we are looking in for the role datum + * types the array of string types which we expect the role has in its type ebitmap + * len number of elements in types + * flags the expected flags in the role typeset (eg., * or ~) + * + * This is a utility function to test whether the type set associated with a role in a specific + * avrule decl block matches our expectations + */ +extern role_datum_t *test_role_type_set(policydb_t * p, const char *id, avrule_decl_t * decl, const char **types, unsigned int len, unsigned int flags); + +/* p the policy being inspected + * id string attribute identifier + * decl the decl block which we are looking in for the attribute datum + * types the array of string types which we expect the attribute has in its type ebitmap + * len number of elements in types + * + * This is a utility function to test whether the type set associated with an attribute in a specific + * avrule decl block matches our expectations + */ +extern void test_attr_types(policydb_t * p, const char *id, avrule_decl_t * decl, const char **types, int len); + +#endif diff --git a/kernel/libsepol/tests/test-cond.c b/kernel/libsepol/tests/test-cond.c new file mode 100644 index 00000000..88e4c971 --- /dev/null +++ b/kernel/libsepol/tests/test-cond.c @@ -0,0 +1,95 @@ +/* + * Author: Karl MacMillan + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-cond.h" +#include "parse_util.h" +#include "helpers.h" + +#include +#include +#include +#include + +static policydb_t basemod; +static policydb_t base_expanded; + +int cond_test_init(void) +{ + if (policydb_init(&base_expanded)) { + fprintf(stderr, "out of memory!\n"); + ksu_policydb_destroy(&basemod); + return -1; + } + + if (test_load_policy(&basemod, POLICY_BASE, 1, "test-cond", "refpolicy-base.conf")) + goto cleanup; + + if (link_modules(NULL, &basemod, NULL, 0, 0)) { + fprintf(stderr, "link modules failed\n"); + goto cleanup; + } + + if (expand_module(NULL, &basemod, &base_expanded, 0, 1)) { + fprintf(stderr, "expand module failed\n"); + goto cleanup; + } + + return 0; + + cleanup: + ksu_policydb_destroy(&basemod); + ksu_policydb_destroy(&base_expanded); + return -1; +} + +int cond_test_cleanup(void) +{ + ksu_policydb_destroy(&basemod); + ksu_policydb_destroy(&base_expanded); + + return 0; +} + +static void test_cond_expr_equal(void) +{ + cond_node_t *a, *b; + + a = base_expanded.cond_list; + while (a) { + b = base_expanded.cond_list; + while (b) { + if (a == b) { + CU_ASSERT(cond_expr_equal(a, b)); + } else { + CU_ASSERT(cond_expr_equal(a, b) == 0); + } + b = b->next; + } + a = a->next; + } +} + +int cond_add_tests(CU_pSuite suite) +{ + if (NULL == CU_add_test(suite, "cond_expr_equal", test_cond_expr_equal)) { + return CU_get_error(); + } + return 0; +} diff --git a/kernel/libsepol/tests/test-cond.h b/kernel/libsepol/tests/test-cond.h new file mode 100644 index 00000000..702d9e01 --- /dev/null +++ b/kernel/libsepol/tests/test-cond.h @@ -0,0 +1,30 @@ +/* + * Author: Karl MacMillan + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_COND_H__ +#define __TEST_COND_H__ + +#include + +int cond_test_init(void); +int cond_test_cleanup(void); +int cond_add_tests(CU_pSuite suite); + +#endif diff --git a/kernel/libsepol/tests/test-deps.c b/kernel/libsepol/tests/test-deps.c new file mode 100644 index 00000000..d139ac11 --- /dev/null +++ b/kernel/libsepol/tests/test-deps.c @@ -0,0 +1,306 @@ +/* + * Author: Karl MacMillan + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-deps.h" +#include "parse_util.h" +#include "helpers.h" + +#include +#include + +#include + +/* Tests for dependency checking / handling, specifically: + * + * 1 type in module global. + * 2 attribute in module global. + * 3 object class / perm in module global. + * 4 boolean in module global. + * 5 role in module global. + * + * 6 type in module optional. + * 7 attribute in module optional. + * 8 object class / perm in module optional. + * 9 boolean in module optional. + * 10 role in module optional. + * + * 11 type in base optional. + * 12 attribute in base optional. + * 13 object class / perm in base optional. + * 14 boolean in base optional. + * 15 role in base optional. + * + * Each of these tests are done with the dependency met and not + * met. Additionally, each of the required symbols is used in the + * scope it is required. + * + * In addition to the simple tests, we have test with more complex + * modules that test: + * + * 17 mutual dependencies between two modules. + * 18 circular dependency between three modules. + * 19 large number of dependencies in a module with a more complex base. + * 20 nested optionals with requires. + * + * Again, each of these tests is done with the requirements met and not + * met. + */ + +#include +#include + +#include "helpers.h" + +#define BASE_MODREQ_TYPE_GLOBAL 0 +#define BASE_MODREQ_ATTR_GLOBAL 1 +#define BASE_MODREQ_OBJ_GLOBAL 2 +#define BASE_MODREQ_BOOL_GLOBAL 3 +#define BASE_MODREQ_ROLE_GLOBAL 4 +#define BASE_MODREQ_PERM_GLOBAL 5 +#define BASE_MODREQ_TYPE_OPT 6 +#define BASE_MODREQ_ATTR_OPT 7 +#define BASE_MODREQ_OBJ_OPT 8 +#define BASE_MODREQ_BOOL_OPT 9 +#define BASE_MODREQ_ROLE_OPT 10 +#define BASE_MODREQ_PERM_OPT 11 +#define NUM_BASES 12 + +static policydb_t bases_met[NUM_BASES]; +static policydb_t bases_notmet[NUM_BASES]; + +extern int mls; + +int deps_test_init(void) +{ + int i; + + /* To test linking we need 1 base per link test and in + * order to load them in the init function we have + * to keep them all around. Not ideal, but it shouldn't + * matter too much. + */ + for (i = 0; i < NUM_BASES; i++) { + if (test_load_policy(&bases_met[i], POLICY_BASE, mls, "test-deps", "base-metreq.conf")) + return -1; + } + + for (i = 0; i < NUM_BASES; i++) { + if (test_load_policy(&bases_notmet[i], POLICY_BASE, mls, "test-deps", "base-notmetreq.conf")) + return -1; + } + + return 0; +} + +int deps_test_cleanup(void) +{ + int i; + + for (i = 0; i < NUM_BASES; i++) { + ksu_policydb_destroy(&bases_met[i]); + } + + for (i = 0; i < NUM_BASES; i++) { + ksu_policydb_destroy(&bases_notmet[i]); + } + + return 0; +} + +/* This function performs testing of the dependency handles for module global + * symbols. It is capable of testing 2 scenarios - the dependencies are met + * and the dependencies are not met. + * + * Parameters: + * req_met boolean indicating whether the base policy meets the + * requirements for the modules global block. + * b index of the base policy in the global bases_met array. + * + * policy name of the policy module to load for this test. + * decl_type name of the unique type found in the module's global + * section is to find that avrule_decl. + */ +static void do_deps_modreq_global(int req_met, int b, const char *policy, const char *decl_type) +{ + policydb_t *base; + policydb_t mod; + policydb_t *mods[] = { &mod }; + avrule_decl_t *decl; + int ret, link_ret; + sepol_handle_t *h; + + /* suppress error reporting - this is because we know that we + * are going to get errors and don't want libsepol complaining + * about it constantly. */ + h = sepol_handle_create(); + CU_ASSERT_FATAL(h != NULL); + sepol_msg_set_callback(h, NULL, NULL); + + if (req_met) { + base = &bases_met[b]; + link_ret = 0; + } else { + base = &bases_notmet[b]; + link_ret = -3; + } + + CU_ASSERT_FATAL(test_load_policy(&mod, POLICY_MOD, mls, "test-deps", policy) == 0); + + /* link the modules and check for the correct return value. + */ + ret = link_modules(h, base, mods, 1, 0); + CU_ASSERT_FATAL(ret == link_ret); + ksu_policydb_destroy(&mod); + sepol_handle_destroy(h); + + if (!req_met) + return; + + decl = test_find_decl_by_sym(base, SYM_TYPES, decl_type); + CU_ASSERT_FATAL(decl != NULL); + + CU_ASSERT(decl->enabled == 1); +} + +/* Test that symbol require statements in the global scope of a module + * work correctly. This will cover tests 1 - 5 (described above). + * + * Each of these policies will require as few symbols as possible to + * use the required symbol in addition requiring (for example, the type + * test also requires an object class for an allow rule). + */ +static void deps_modreq_global(void) +{ + /* object classes */ + do_deps_modreq_global(1, BASE_MODREQ_OBJ_GLOBAL, "modreq-obj-global.conf", "mod_global_t"); + do_deps_modreq_global(0, BASE_MODREQ_OBJ_GLOBAL, "modreq-obj-global.conf", "mod_global_t"); + /* types */ + do_deps_modreq_global(1, BASE_MODREQ_TYPE_GLOBAL, "modreq-type-global.conf", "mod_global_t"); + do_deps_modreq_global(0, BASE_MODREQ_TYPE_GLOBAL, "modreq-type-global.conf", "mod_global_t"); + /* attributes */ + do_deps_modreq_global(1, BASE_MODREQ_ATTR_GLOBAL, "modreq-attr-global.conf", "mod_global_t"); + do_deps_modreq_global(0, BASE_MODREQ_ATTR_GLOBAL, "modreq-attr-global.conf", "mod_global_t"); + /* booleans */ + do_deps_modreq_global(1, BASE_MODREQ_BOOL_GLOBAL, "modreq-bool-global.conf", "mod_global_t"); + do_deps_modreq_global(0, BASE_MODREQ_BOOL_GLOBAL, "modreq-bool-global.conf", "mod_global_t"); + /* roles */ + do_deps_modreq_global(1, BASE_MODREQ_ROLE_GLOBAL, "modreq-role-global.conf", "mod_global_t"); + do_deps_modreq_global(0, BASE_MODREQ_ROLE_GLOBAL, "modreq-role-global.conf", "mod_global_t"); + do_deps_modreq_global(1, BASE_MODREQ_PERM_GLOBAL, "modreq-perm-global.conf", "mod_global_t"); + do_deps_modreq_global(0, BASE_MODREQ_PERM_GLOBAL, "modreq-perm-global.conf", "mod_global_t"); +} + +/* This function performs testing of the dependency handles for module optional + * symbols. It is capable of testing 2 scenarios - the dependencies are met + * and the dependencies are not met. + * + * Parameters: + * req_met boolean indicating whether the base policy meets the + * requirements for the modules global block. + * b index of the base policy in the global bases_met array. + * + * policy name of the policy module to load for this test. + * decl_type name of the unique type found in the module's global + * section is to find that avrule_decl. + */ +static void do_deps_modreq_opt(int req_met, int ret_val, int b, const char *policy, const char *decl_type) +{ + policydb_t *base; + policydb_t mod; + policydb_t *mods[] = { &mod }; + avrule_decl_t *decl; + int ret; + sepol_handle_t *h; + + /* suppress error reporting - this is because we know that we + * are going to get errors and don't want libsepol complaining + * about it constantly. */ + h = sepol_handle_create(); + CU_ASSERT_FATAL(h != NULL); + sepol_msg_set_callback(h, NULL, NULL); + + if (req_met) { + base = &bases_met[b]; + } else { + base = &bases_notmet[b]; + } + + CU_ASSERT_FATAL(test_load_policy(&mod, POLICY_MOD, mls, "test-deps", policy) == 0); + + /* link the modules and check for the correct return value. + */ + ret = link_modules(h, base, mods, 1, 0); + CU_ASSERT_FATAL(ret == ret_val); + ksu_policydb_destroy(&mod); + sepol_handle_destroy(h); + if (ret_val < 0) + return; + + decl = test_find_decl_by_sym(base, SYM_TYPES, decl_type); + CU_ASSERT_FATAL(decl != NULL); + + if (req_met) { + CU_ASSERT(decl->enabled == 1); + } else { + CU_ASSERT(decl->enabled == 0); + } +} + +/* Test that symbol require statements in the global scope of a module + * work correctly. This will cover tests 6 - 10 (described above). + * + * Each of these policies will require as few symbols as possible to + * use the required symbol in addition requiring (for example, the type + * test also requires an object class for an allow rule). + */ +static void deps_modreq_opt(void) +{ + /* object classes */ + do_deps_modreq_opt(1, 0, BASE_MODREQ_OBJ_OPT, "modreq-obj-opt.conf", "mod_opt_t"); + do_deps_modreq_opt(0, 0, BASE_MODREQ_OBJ_OPT, "modreq-obj-opt.conf", "mod_opt_t"); + /* types */ + do_deps_modreq_opt(1, 0, BASE_MODREQ_TYPE_OPT, "modreq-type-opt.conf", "mod_opt_t"); + do_deps_modreq_opt(0, 0, BASE_MODREQ_TYPE_OPT, "modreq-type-opt.conf", "mod_opt_t"); + /* attributes */ + do_deps_modreq_opt(1, 0, BASE_MODREQ_ATTR_OPT, "modreq-attr-opt.conf", "mod_opt_t"); + do_deps_modreq_opt(0, 0, BASE_MODREQ_ATTR_OPT, "modreq-attr-opt.conf", "mod_opt_t"); + /* booleans */ + do_deps_modreq_opt(1, 0, BASE_MODREQ_BOOL_OPT, "modreq-bool-opt.conf", "mod_opt_t"); + do_deps_modreq_opt(0, 0, BASE_MODREQ_BOOL_OPT, "modreq-bool-opt.conf", "mod_opt_t"); + /* roles */ + do_deps_modreq_opt(1, 0, BASE_MODREQ_ROLE_OPT, "modreq-role-opt.conf", "mod_opt_t"); + do_deps_modreq_opt(0, 0, BASE_MODREQ_ROLE_OPT, "modreq-role-opt.conf", "mod_opt_t"); + /* permissions */ + do_deps_modreq_opt(1, 0, BASE_MODREQ_PERM_OPT, "modreq-perm-opt.conf", "mod_opt_t"); + do_deps_modreq_opt(0, -3, BASE_MODREQ_PERM_OPT, "modreq-perm-opt.conf", "mod_opt_t"); +} + +int deps_add_tests(CU_pSuite suite) +{ + if (NULL == CU_add_test(suite, "deps_modreq_global", deps_modreq_global)) { + return CU_get_error(); + } + + if (NULL == CU_add_test(suite, "deps_modreq_opt", deps_modreq_opt)) { + return CU_get_error(); + } + + return 0; +} diff --git a/kernel/libsepol/tests/test-deps.h b/kernel/libsepol/tests/test-deps.h new file mode 100644 index 00000000..fbd2ace5 --- /dev/null +++ b/kernel/libsepol/tests/test-deps.h @@ -0,0 +1,30 @@ +/* + * Author: Karl MacMillan + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_DEPS_H__ +#define __TEST_DEPS_H__ + +#include + +int deps_test_init(void); +int deps_test_cleanup(void); +int deps_add_tests(CU_pSuite suite); + +#endif diff --git a/kernel/libsepol/tests/test-downgrade.c b/kernel/libsepol/tests/test-downgrade.c new file mode 100644 index 00000000..b25f898c --- /dev/null +++ b/kernel/libsepol/tests/test-downgrade.c @@ -0,0 +1,271 @@ +/* + * Author: Mary Garvin + * + * Copyright (C) 2007-2008 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-downgrade.h" +#include "parse_util.h" +#include "helpers.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define POLICY_BIN_HI "policies/test-downgrade/policy.hi" +#define POLICY_BIN_LO "policies/test-downgrade/policy.lo" + +static policydb_t policydb; + +/* + * Function Name: downgrade_test_init + * + * Input: None + * + * Output: None + * + * Description: Initialize the policydb (policy data base structure) + */ +int downgrade_test_init(void) +{ + /* Initialize the policydb_t structure */ + if (policydb_init(&policydb)) { + fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__); + return -1; + } + + return 0; +} + +/* + * Function Name: downgrade_test_cleanup + * + * Input: None + * + * Output: None + * + * Description: Destroys policydb structure + */ +int downgrade_test_cleanup(void) +{ + ksu_policydb_destroy(&policydb); + + return 0; +} + +/* + * Function Name: downgrade_add_tests + * + * Input: CU_pSuite + * + * Output: Returns 0 upon success. Returns a CUnit error value on failure. + * + * Description: Add the given downgrade tests to the downgrade suite. + */ +int downgrade_add_tests(CU_pSuite suite) +{ + if (CU_add_test(suite, "downgrade", test_downgrade) == NULL) + return CU_get_error(); + + return 0; +} + +/* + * Function Name: test_downgrade_possible + * + * Input: None + * + * Output: None + * + * Description: + * Tests the backward compatibility of MLS and Non-MLS binary policy versions. + */ +void test_downgrade(void) +{ + if (do_downgrade_test(0) < 0) + fprintf(stderr, + "\nError during downgrade testing of Non-MLS policy\n"); + + + if (do_downgrade_test(1) < 0) + fprintf(stderr, + "\nError during downgrade testing of MLS policy\n"); +} + +/* + * Function Name: do_downgrade_test + * + * Input: 0 for Non-MLS policy and 1 for MLS policy downgrade testing + * + * Output: 0 on success, negative number upon failure + * + * Description: This function handles the downgrade testing. + * A binary policy is read into the policydb structure, the + * policy version is decreased by a specific amount, written + * back out and then read back in again. The process is + * repeated until the minimum policy version is reached. + */ +int do_downgrade_test(int mls) +{ + policydb_t policydb_tmp; + int hi, lo, version; + + /* Reset policydb for re-use */ + ksu_policydb_destroy(&policydb); + downgrade_test_init(); + + /* Read in the hi policy from file */ + if (read_binary_policy(POLICY_BIN_HI, &policydb) != 0) { + fprintf(stderr, "error reading %spolicy binary\n", mls ? "mls " : ""); + CU_FAIL("Unable to read the binary policy"); + return -1; + } + + /* Change MLS value based on parameter */ + policydb.mls = mls ? 1 : 0; + + for (hi = policydb.policyvers; hi >= POLICYDB_VERSION_MIN; hi--) { + /* Stash old version number */ + version = policydb.policyvers; + + /* Try downgrading to each possible version. */ + for (lo = hi - 1; lo >= POLICYDB_VERSION_MIN; lo--) { + + /* Reduce policy version */ + policydb.policyvers = lo; + + /* Write out modified binary policy */ + if (write_binary_policy(POLICY_BIN_LO, &policydb) != 0) { + /* + * Error from MLS to pre-MLS is expected due + * to MLS re-implementation in version 19. + */ + if (mls && lo < POLICYDB_VERSION_MLS) + continue; + + fprintf(stderr, "error writing %spolicy binary, version %d (downgraded from %d)\n", mls ? "mls " : "", lo, hi); + CU_FAIL("Failed to write downgraded binary policy"); + return -1; + } + + /* Make sure we can read back what we wrote. */ + if (policydb_init(&policydb_tmp)) { + fprintf(stderr, "%s: Out of memory!\n", + __FUNCTION__); + return -1; + } + if (read_binary_policy(POLICY_BIN_LO, &policydb_tmp) != 0) { + fprintf(stderr, "error reading %spolicy binary, version %d (downgraded from %d)\n", mls ? "mls " : "", lo, hi); + CU_FAIL("Unable to read downgraded binary policy"); + return -1; + } + ksu_policydb_destroy(&policydb_tmp); + } + /* Restore version number */ + policydb.policyvers = version; + } + + return 0; +} + +/* + * Function Name: read_binary_policy + * + * Input: char * which is the path to the file containing the binary policy + * + * Output: Returns 0 upon success. Upon failure, -1 is returned. + * Possible failures are, filename with given path does not exist, + * a failure to open the file, or a failure from prolicydb_read + * function call. + * + * Description: Get a filename, open file and read binary policy into policydb + * structure. + */ +int read_binary_policy(const char *path, policydb_t *p) +{ + FILE *in_fp = NULL; + struct policy_file f; + int rc; + + /* Open the binary policy file */ + if ((in_fp = fopen(path, "rb")) == NULL) { + fprintf(stderr, "Unable to open %s: %s\n", path, + strerror(errno)); + return -1; + } + + /* Read in the binary policy. */ + memset(&f, 0, sizeof(struct policy_file)); + f.type = PF_USE_STDIO; + f.fp = in_fp; + rc = ksu_policydb_read(p, &f, 0); + + fclose(in_fp); + return rc; +} + +/* + * Function Name: write_binary_policy + * + * Input: char * which is the path to the file containing the binary policy + * + * Output: Returns 0 upon success. Upon failure, -1 is returned. + * Possible failures are, filename with given path does not exist, + * a failure to open the file, or a failure from prolicydb_read + * function call. + * + * Description: open file and write the binary policy from policydb structure. + */ +int write_binary_policy(const char *path, policydb_t *p) +{ + FILE *out_fp = NULL; + struct policy_file f; + sepol_handle_t *handle; + int rc; + + /* We don't want libsepol to print warnings to stderr */ + handle = sepol_handle_create(); + if (handle == NULL) { + fprintf(stderr, "Out of memory!\n"); + return -1; + } + sepol_msg_set_callback(handle, NULL, NULL); + + /* Open the binary policy file for writing */ + if ((out_fp = fopen(path, "w" )) == NULL) { + fprintf(stderr, "Unable to open %s: %s\n", path, + strerror(errno)); + sepol_handle_destroy(handle); + return -1; + } + + /* Write the binary policy */ + memset(&f, 0, sizeof(struct policy_file)); + f.type = PF_USE_STDIO; + f.fp = out_fp; + f.handle = handle; + rc = ksu_policydb_write(p, &f); + + sepol_handle_destroy(f.handle); + fclose(out_fp); + return rc; +} diff --git a/kernel/libsepol/tests/test-downgrade.h b/kernel/libsepol/tests/test-downgrade.h new file mode 100644 index 00000000..4105defa --- /dev/null +++ b/kernel/libsepol/tests/test-downgrade.h @@ -0,0 +1,119 @@ +/* + * Author: Mary Garvin + * + * Copyright (C) 2007-2008 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_DOWNGRADE_H__ +#define __TEST_DOWNGRADE_H__ + +#include +#include + +/* + * Function Name: downgrade_test_init + * + * Input: None + * + * Output: None + * + * Description: Initialize the policydb (policy data base structure) + */ +int downgrade_test_init(void); + +/* + * Function Name: downgrade_test_cleanup + * + * Input: None + * + * Output: None + * + * Description: Destroys policydb structure + */ +int downgrade_test_cleanup(void); + +/* + * Function Name: downgrade_add_tests + * + * Input: CU_pSuite + * + * Output: Returns 0 upon success. Upon failure, a CUnit testing error + * value is returned + * + * Description: Add the given downgrade tests to the downgrade suite. + */ +int downgrade_add_tests(CU_pSuite suite); + +/* + * Function Name: test_downgrade_possible + * + * Input: None + * + * Output: None + * + * Description: Tests the backward compatibility of MLS and Non-MLS binary + * policy versions. + */ +void test_downgrade(void); + +/* + * Function Name: do_downgrade_test + * + * Input: int that represents a 0 for Non-MLS policy and a + * 1 for MLS policy downgrade testing + * + * Output: (int) 0 on success, negative number upon failure + * + * Description: This function handles the downgrade testing. A binary policy + * is read into the policydb structure, the policy version is + * decreased by a specific amount, written back out and then read + * back in again. The process is iterative until the minimum + * policy version is reached. + */ +int do_downgrade_test(int mls); + +/* + * Function Name: read_binary_policy + * + * Input: char * which is the path to the file containing the binary policy + * + * Output: Returns 0 upon success. Upon failure, -1 is returned. + * Possible failures are, filename with given path does not exist, + * a failure to open the file, or a failure from prolicydb_read + * function call. + * + * Description: Get a filename, open file and read in the binary policy + * into the policydb structure. + */ +int read_binary_policy(const char *path, policydb_t *); + +/* + * Function Name: write_binary_policy + * + * Input: char * which is the path to the file containing the binary policy + * + * Output: Returns 0 upon success. Upon failure, -1 is returned. + * Possible failures are, filename with given path does not exist, + * a failure to open the file, or a failure from prolicydb_read + * function call. + * + * Description: Get a filename, open file and read in the binary policy + * into the policydb structure. + */ +int write_binary_policy(const char *path, policydb_t *); + +#endif diff --git a/kernel/libsepol/tests/test-expander-attr-map.c b/kernel/libsepol/tests/test-expander-attr-map.c new file mode 100644 index 00000000..a9744541 --- /dev/null +++ b/kernel/libsepol/tests/test-expander-attr-map.c @@ -0,0 +1,106 @@ +/* + * Authors: Chad Sellers + * Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-expander-attr-map.h" +#include "test-common.h" +#include "helpers.h" + +#include +#include +#include + +extern policydb_t base_expanded2; + +void test_expander_attr_mapping(void) +{ + /* note that many cases are omitted because they don't make sense + (i.e. declaring in an optional and then using it in the base) or + because declare in optional then require in a different optional + logic still doesn't work */ + + const char *typesb1[] = { "attr_check_base_1_1_t", "attr_check_base_1_2_t" }; + const char *typesb2[] = { "attr_check_base_2_1_t", "attr_check_base_2_2_t" }; + const char *typesb3[] = { "attr_check_base_3_1_t", "attr_check_base_3_2_t", + "attr_check_base_3_3_t", "attr_check_base_3_4_t" + }; + const char *typesb4[] = { "attr_check_base_4_1_t", "attr_check_base_4_2_t" }; + const char *typesb5[] = { "attr_check_base_5_1_t", "attr_check_base_5_2_t" }; + const char *typesb6[] = { "attr_check_base_6_1_t", "attr_check_base_6_2_t", + "attr_check_base_6_3_t", "attr_check_base_6_4_t" + }; + const char *typesbo2[] = { "attr_check_base_optional_2_1_t", + "attr_check_base_optional_2_2_t" + }; + const char *typesbo5[] = { "attr_check_base_optional_5_1_t", + "attr_check_base_optional_5_2_t" + }; + const char *typesm2[] = { "attr_check_mod_2_1_t", "attr_check_mod_2_2_t" }; + const char *typesm4[] = { "attr_check_mod_4_1_t", "attr_check_mod_4_2_t" }; + const char *typesm5[] = { "attr_check_mod_5_1_t", "attr_check_mod_5_2_t" }; + const char *typesm6[] = { "attr_check_mod_6_1_t", "attr_check_mod_6_2_t", + "attr_check_mod_6_3_t", "attr_check_mod_6_4_t" + }; + const char *typesmo2[] = { "attr_check_mod_optional_4_1_t", + "attr_check_mod_optional_4_2_t" + }; + const char *typesb10[] = { "attr_check_base_10_1_t", "attr_check_base_10_2_t" }; + const char *typesb11[] = { "attr_check_base_11_3_t", "attr_check_base_11_4_t" }; + const char *typesm10[] = { "attr_check_mod_10_1_t", "attr_check_mod_10_2_t" }; + const char *typesm11[] = { "attr_check_mod_11_3_t", "attr_check_mod_11_4_t" }; + + test_attr_types(&base_expanded2, "attr_check_base_1", NULL, typesb1, 2); + test_attr_types(&base_expanded2, "attr_check_base_2", NULL, typesb2, 2); + test_attr_types(&base_expanded2, "attr_check_base_3", NULL, typesb3, 4); + test_attr_types(&base_expanded2, "attr_check_base_4", NULL, typesb4, 2); + test_attr_types(&base_expanded2, "attr_check_base_5", NULL, typesb5, 2); + test_attr_types(&base_expanded2, "attr_check_base_6", NULL, typesb6, 4); + test_attr_types(&base_expanded2, "attr_check_base_optional_2", NULL, typesbo2, 2); + test_attr_types(&base_expanded2, "attr_check_base_optional_5", NULL, typesbo5, 2); + test_attr_types(&base_expanded2, "attr_check_mod_2", NULL, typesm2, 2); + test_attr_types(&base_expanded2, "attr_check_mod_4", NULL, typesm4, 2); + test_attr_types(&base_expanded2, "attr_check_mod_5", NULL, typesm5, 2); + test_attr_types(&base_expanded2, "attr_check_mod_6", NULL, typesm6, 4); + test_attr_types(&base_expanded2, "attr_check_mod_optional_4", NULL, typesmo2, 2); + test_attr_types(&base_expanded2, "attr_check_base_7", NULL, NULL, 0); + test_attr_types(&base_expanded2, "attr_check_base_8", NULL, NULL, 0); + test_attr_types(&base_expanded2, "attr_check_base_9", NULL, NULL, 0); + test_attr_types(&base_expanded2, "attr_check_base_10", NULL, typesb10, 2); + test_attr_types(&base_expanded2, "attr_check_base_11", NULL, typesb11, 2); + test_attr_types(&base_expanded2, "attr_check_mod_7", NULL, NULL, 0); + test_attr_types(&base_expanded2, "attr_check_mod_8", NULL, NULL, 0); + test_attr_types(&base_expanded2, "attr_check_mod_9", NULL, NULL, 0); + test_attr_types(&base_expanded2, "attr_check_mod_10", NULL, typesm10, 2); + test_attr_types(&base_expanded2, "attr_check_mod_11", NULL, typesm11, 2); + test_attr_types(&base_expanded2, "attr_check_base_optional_8", NULL, NULL, 0); + test_attr_types(&base_expanded2, "attr_check_mod_optional_7", NULL, NULL, 0); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_base_optional_disabled_5")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_base_optional_disabled_5_1_t")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_base_optional_disabled_5_2_t")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_base_optional_disabled_8")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_base_optional_disabled_8_1_t")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_base_optional_disabled_8_2_t")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_mod_optional_disabled_4")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_mod_optional_disabled_4_1_t")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_mod_optional_disabled_4_2_t")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_mod_optional_disabled_7")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_mod_optional_disabled_7_1_t")); + CU_ASSERT(!hashtab_search((&base_expanded2)->p_types.table, "attr_check_mod_optional_disabled_7_2_t")); +} diff --git a/kernel/libsepol/tests/test-expander-attr-map.h b/kernel/libsepol/tests/test-expander-attr-map.h new file mode 100644 index 00000000..6a100893 --- /dev/null +++ b/kernel/libsepol/tests/test-expander-attr-map.h @@ -0,0 +1,26 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_EXPANDER__ATTR_MAP_H__ +#define __TEST_EXPANDER__ATTR_MAP_H__ + +void test_expander_attr_mapping(void); + +#endif diff --git a/kernel/libsepol/tests/test-expander-roles.c b/kernel/libsepol/tests/test-expander-roles.c new file mode 100644 index 00000000..74c781b8 --- /dev/null +++ b/kernel/libsepol/tests/test-expander-roles.c @@ -0,0 +1,38 @@ +/* + * Authors: Chad Sellers + * Joshua Brindle + * Chris PeBenito + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-expander-roles.h" +#include "test-common.h" +#include "helpers.h" + +#include +#include +#include + +extern policydb_t role_expanded; + +void test_expander_role_mapping(void) +{ + const char *types1[] = { "role_check_1_1_t", "role_check_1_2_t" }; + + test_role_type_set(&role_expanded, "role_check_1", NULL, types1, 2, 0); +} diff --git a/kernel/libsepol/tests/test-expander-roles.h b/kernel/libsepol/tests/test-expander-roles.h new file mode 100644 index 00000000..380d2eff --- /dev/null +++ b/kernel/libsepol/tests/test-expander-roles.h @@ -0,0 +1,27 @@ +/* + * Author: Joshua Brindle + * Author: Chris PeBenito + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_EXPANDER_ROLE_H__ +#define __TEST_EXPANDER_ROLE_H__ + +void test_expander_role_mapping(void); + +#endif diff --git a/kernel/libsepol/tests/test-expander-users.c b/kernel/libsepol/tests/test-expander-users.c new file mode 100644 index 00000000..ab2265c1 --- /dev/null +++ b/kernel/libsepol/tests/test-expander-users.c @@ -0,0 +1,74 @@ +/* + * Authors: Chad Sellers + * Joshua Brindle + * Chris PeBenito + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-expander-users.h" +#include "helpers.h" + +#include +#include +#include + +extern policydb_t user_expanded; + +static void check_user_roles(policydb_t * p, const char *user_name, const char **role_names, int num_roles) +{ + user_datum_t *user; + ebitmap_node_t *tnode; + unsigned int i; + int j; + unsigned char *found; /* array of booleans of roles found */ + int extra = 0; /* number of extra roles found */ + + user = (user_datum_t *) hashtab_search(p->p_users.table, user_name); + if (!user) { + printf("%s not found\n", user_name); + CU_FAIL("user not found"); + return; + } + found = calloc(num_roles, sizeof(unsigned char)); + CU_ASSERT_FATAL(found != NULL); + ebitmap_for_each_positive_bit(&user->roles.roles, tnode, i) { + extra++; + for (j = 0; j < num_roles; j++) { + if (strcmp(role_names[j], p->p_role_val_to_name[i]) == 0) { + extra--; + found[j] += 1; + break; + } + } + } + for (j = 0; j < num_roles; j++) { + if (found[j] != 1) { + printf("role %s associated with user %s %d times\n", role_names[j], user_name, found[j]); + CU_FAIL("user mapping failure\n"); + } + } + free(found); + CU_ASSERT_EQUAL(extra, 0); +} + +void test_expander_user_mapping(void) +{ + const char *roles1[] = { "user_check_1_1_r", "user_check_1_2_r" }; + + check_user_roles(&user_expanded, "user_check_1", roles1, 2); +} diff --git a/kernel/libsepol/tests/test-expander-users.h b/kernel/libsepol/tests/test-expander-users.h new file mode 100644 index 00000000..cb12143c --- /dev/null +++ b/kernel/libsepol/tests/test-expander-users.h @@ -0,0 +1,27 @@ +/* + * Author: Joshua Brindle + * Author: Chris PeBenito + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_EXPANDER_USER_H__ +#define __TEST_EXPANDER_USER_H__ + +void test_expander_user_mapping(void); + +#endif diff --git a/kernel/libsepol/tests/test-expander.c b/kernel/libsepol/tests/test-expander.c new file mode 100644 index 00000000..4a11615b --- /dev/null +++ b/kernel/libsepol/tests/test-expander.c @@ -0,0 +1,235 @@ +/* + * Authors: Chad Sellers + * Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This is where the expander tests should go, including: + * - check role, type, bool, user mapping + * - add symbols declared in enabled optionals + * - do not add symbols declared in disabled optionals + * - add rules from enabled optionals + * - do not add rules from disabled optionals + * - verify attribute mapping + + * - check conditional expressions for correct mapping + */ + +#include "test-expander.h" +#include "parse_util.h" +#include "helpers.h" +#include "test-common.h" +#include "test-expander-users.h" +#include "test-expander-roles.h" +#include "test-expander-attr-map.h" + +#include +#include +#include +#include +#include +#include + +policydb_t role_expanded; +policydb_t user_expanded; +policydb_t base_expanded2; +static policydb_t basemod; +static policydb_t basemod2; +static policydb_t mod2; +static policydb_t base_expanded; +static policydb_t base_only_mod; +static policydb_t base_only_expanded; +static policydb_t role_basemod; +static policydb_t role_mod; +static policydb_t user_basemod; +static policydb_t user_mod; +static policydb_t alias_basemod; +static policydb_t alias_mod; +static policydb_t alias_expanded; +static uint32_t *typemap; +extern int mls; + +/* Takes base, some number of modules, links them, and expands them + reads source from myfiles array, which has the base string followed by + each module string */ +static int expander_policy_init(policydb_t * mybase, int num_modules, policydb_t ** mymodules, policydb_t * myexpanded, const char *const *myfiles) +{ + char *filename[num_modules + 1]; + int i; + + for (i = 0; i < num_modules + 1; i++) { + filename[i] = calloc(PATH_MAX, sizeof(char)); + if (snprintf(filename[i], PATH_MAX, "policies/test-expander/%s%s", myfiles[i], mls ? ".mls" : ".std") < 0) + return -1; + } + + if (policydb_init(mybase)) { + fprintf(stderr, "out of memory!\n"); + return -1; + } + + for (i = 0; i < num_modules; i++) { + if (policydb_init(mymodules[i])) { + fprintf(stderr, "out of memory!\n"); + return -1; + } + } + + if (policydb_init(myexpanded)) { + fprintf(stderr, "out of memory!\n"); + return -1; + } + + mybase->policy_type = POLICY_BASE; + mybase->mls = mls; + + if (read_source_policy(mybase, filename[0], myfiles[0])) { + fprintf(stderr, "read source policy failed %s\n", filename[0]); + return -1; + } + + for (i = 1; i < num_modules + 1; i++) { + mymodules[i - 1]->policy_type = POLICY_MOD; + mymodules[i - 1]->mls = mls; + if (read_source_policy(mymodules[i - 1], filename[i], myfiles[i])) { + fprintf(stderr, "read source policy failed %s\n", filename[i]); + return -1; + } + } + + if (link_modules(NULL, mybase, mymodules, num_modules, 0)) { + fprintf(stderr, "link modules failed\n"); + return -1; + } + + if (expand_module(NULL, mybase, myexpanded, 0, 0)) { + fprintf(stderr, "expand modules failed\n"); + return -1; + } + + for (i = 0; i < num_modules + 1; i++) { + free(filename[i]); + } + return 0; +} + +int expander_test_init(void) +{ + const char *small_base_file = "small-base.conf"; + const char *base_only_file = "base-base-only.conf"; + int rc; + policydb_t *mymod2; + const char *files2[] = { "small-base.conf", "module.conf" }; + const char *role_files[] = { "role-base.conf", "role-module.conf" }; + const char *user_files[] = { "user-base.conf", "user-module.conf" }; + const char *alias_files[] = { "alias-base.conf", "alias-module.conf" }; + + rc = expander_policy_init(&basemod, 0, NULL, &base_expanded, &small_base_file); + if (rc != 0) + return rc; + + mymod2 = &mod2; + rc = expander_policy_init(&basemod2, 1, &mymod2, &base_expanded2, files2); + if (rc != 0) + return rc; + + rc = expander_policy_init(&base_only_mod, 0, NULL, &base_only_expanded, &base_only_file); + if (rc != 0) + return rc; + + mymod2 = &role_mod; + rc = expander_policy_init(&role_basemod, 1, &mymod2, &role_expanded, role_files); + if (rc != 0) + return rc; + + /* Just init the base for now, until we figure out how to separate out + mls and non-mls tests since users can't be used in mls module */ + mymod2 = &user_mod; + rc = expander_policy_init(&user_basemod, 0, NULL, &user_expanded, user_files); + if (rc != 0) + return rc; + + mymod2 = &alias_mod; + rc = expander_policy_init(&alias_basemod, 1, &mymod2, &alias_expanded, alias_files); + if (rc != 0) + return rc; + + return 0; +} + +int expander_test_cleanup(void) +{ + ksu_policydb_destroy(&basemod); + ksu_policydb_destroy(&base_expanded); + ksu_policydb_destroy(&basemod2); + ksu_policydb_destroy(&base_expanded2); + ksu_policydb_destroy(&mod2); + ksu_policydb_destroy(&base_only_mod); + ksu_policydb_destroy(&base_only_expanded); + ksu_policydb_destroy(&role_basemod); + ksu_policydb_destroy(&role_expanded); + ksu_policydb_destroy(&role_mod); + ksu_policydb_destroy(&user_basemod); + ksu_policydb_destroy(&user_expanded); + ksu_policydb_destroy(&user_mod); + ksu_policydb_destroy(&alias_basemod); + ksu_policydb_destroy(&alias_expanded); + ksu_policydb_destroy(&alias_mod); + free(typemap); + + return 0; +} + +static void test_expander_indexes(void) +{ + test_policydb_indexes(&base_expanded); +} + +static void test_expander_alias(void) +{ + test_alias_datum(&alias_expanded, "alias_check_1_a", "alias_check_1_t", 1, 0); + test_alias_datum(&alias_expanded, "alias_check_2_a", "alias_check_2_t", 1, 0); + test_alias_datum(&alias_expanded, "alias_check_3_a", "alias_check_3_t", 1, 0); +} + +int expander_add_tests(CU_pSuite suite) +{ + if (NULL == CU_add_test(suite, "expander_indexes", test_expander_indexes)) { + CU_cleanup_registry(); + return CU_get_error(); + } + + if (NULL == CU_add_test(suite, "expander_attr_mapping", test_expander_attr_mapping)) { + CU_cleanup_registry(); + return CU_get_error(); + } + + if (NULL == CU_add_test(suite, "expander_role_mapping", test_expander_role_mapping)) { + CU_cleanup_registry(); + return CU_get_error(); + } + if (NULL == CU_add_test(suite, "expander_user_mapping", test_expander_user_mapping)) { + CU_cleanup_registry(); + return CU_get_error(); + } + if (NULL == CU_add_test(suite, "expander_alias", test_expander_alias)) { + CU_cleanup_registry(); + return CU_get_error(); + } + return 0; +} diff --git a/kernel/libsepol/tests/test-expander.h b/kernel/libsepol/tests/test-expander.h new file mode 100644 index 00000000..59641338 --- /dev/null +++ b/kernel/libsepol/tests/test-expander.h @@ -0,0 +1,30 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_EXPANDER_H__ +#define __TEST_EXPANDER_H__ + +#include + +int expander_test_init(void); +int expander_test_cleanup(void); +int expander_add_tests(CU_pSuite suite); + +#endif diff --git a/kernel/libsepol/tests/test-linker-cond-map.c b/kernel/libsepol/tests/test-linker-cond-map.c new file mode 100644 index 00000000..694a7346 --- /dev/null +++ b/kernel/libsepol/tests/test-linker-cond-map.c @@ -0,0 +1,160 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-linker-cond-map.h" +#include "parse_util.h" +#include "helpers.h" +#include "test-common.h" + +#include +#include +#include + +#include +#include + +/* Tests for conditionals + * Test each cond/bool for these + * - boolean copied correctly (state is correct) + * - conditional expression is correct + * Tests: + * - single boolean in base + * - single boolean in module + * - single boolean in base optional + * - single boolean in module optional + * - 2 booleans in base + * - 2 booleans in module + * - 2 booleans in base optional + * - 2 booleans in module optional + * - 2 booleans, base and module + * - 2 booleans, base optional and module + * - 2 booleans, base optional and module optional + * - 3 booleans, base, base optional, module + * - 4 boolean, base, base optional, module, module optional + */ + +typedef struct test_cond_expr { + const char *bool; + uint32_t expr_type; +} test_cond_expr_t; + +static void test_cond_expr_mapping(policydb_t * p, avrule_decl_t * d, test_cond_expr_t * bools, int len) +{ + int i; + cond_expr_t *expr; + + CU_ASSERT_FATAL(d->cond_list != NULL); + CU_ASSERT_FATAL(d->cond_list->expr != NULL); + + expr = d->cond_list->expr; + + for (i = 0; i < len; i++) { + CU_ASSERT_FATAL(expr != NULL); + + CU_ASSERT(expr->expr_type == bools[i].expr_type); + if (bools[i].bool) { + CU_ASSERT(strcmp(p->sym_val_to_name[SYM_BOOLS][expr->bool - 1], bools[i].bool) == 0); + } + expr = expr->next; + } +} + +static void test_bool_state(policydb_t * p, const char *bool, int state) +{ + cond_bool_datum_t *b; + + b = hashtab_search(p->p_bools.table, bool); + CU_ASSERT_FATAL(b != NULL); + CU_ASSERT(b->state == state); +} + +void base_cond_tests(policydb_t * base) +{ + avrule_decl_t *d; + unsigned int decls[1]; + test_cond_expr_t bools[2]; + + /* these tests look at booleans and conditionals in the base only + * to ensure that they aren't altered or removed during the link process */ + + /* bool existence and state, global scope */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"); + decls[0] = d->decl_id; + test_sym_presence(base, "g_b_bool_1", SYM_BOOLS, SCOPE_DECL, decls, 1); + test_bool_state(base, "g_b_bool_1", 0); + /* conditional expression mapped correctly */ + bools[0].bool = "g_b_bool_1"; + bools[0].expr_type = COND_BOOL; + test_cond_expr_mapping(base, d, bools, 1); + + /* bool existence and state, optional scope */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_b"); + decls[0] = d->decl_id; + test_sym_presence(base, "o1_b_bool_1", SYM_BOOLS, SCOPE_DECL, decls, 1); + test_bool_state(base, "o1_b_bool_1", 1); + /* conditional expression mapped correctly */ + bools[0].bool = "o1_b_bool_1"; + bools[0].expr_type = COND_BOOL; + test_cond_expr_mapping(base, d, bools, 1); + +} + +void module_cond_tests(policydb_t * base) +{ + avrule_decl_t *d; + unsigned int decls[1]; + test_cond_expr_t bools[3]; + + /* bool existence and state, module 1 global scope */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"); + decls[0] = d->decl_id; + test_sym_presence(base, "g_m1_bool_1", SYM_BOOLS, SCOPE_DECL, decls, 1); + test_bool_state(base, "g_m1_bool_1", 1); + /* conditional expression mapped correctly */ + bools[0].bool = "g_m1_bool_1"; + bools[0].expr_type = COND_BOOL; + test_cond_expr_mapping(base, d, bools, 1); + + /* bool existence and state, module 1 optional scope */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_m1"); + decls[0] = d->decl_id; + test_sym_presence(base, "o1_m1_bool_1", SYM_BOOLS, SCOPE_DECL, decls, 1); + test_bool_state(base, "o1_m1_bool_1", 0); + /* conditional expression mapped correctly */ + bools[0].bool = "o1_m1_bool_1"; + bools[0].expr_type = COND_BOOL; + test_cond_expr_mapping(base, d, bools, 1); + + /* bool existence and state, module 2 global scope */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m2"); + decls[0] = d->decl_id; + test_sym_presence(base, "g_m2_bool_1", SYM_BOOLS, SCOPE_DECL, decls, 1); + test_sym_presence(base, "g_m2_bool_2", SYM_BOOLS, SCOPE_DECL, decls, 1); + test_bool_state(base, "g_m2_bool_1", 1); + test_bool_state(base, "g_m2_bool_2", 0); + /* conditional expression mapped correctly */ + bools[0].bool = "g_m2_bool_1"; + bools[0].expr_type = COND_BOOL; + bools[1].bool = "g_m2_bool_2"; + bools[1].expr_type = COND_BOOL; + bools[2].bool = NULL; + bools[2].expr_type = COND_AND; + test_cond_expr_mapping(base, d, bools, 3); +} diff --git a/kernel/libsepol/tests/test-linker-cond-map.h b/kernel/libsepol/tests/test-linker-cond-map.h new file mode 100644 index 00000000..740a722e --- /dev/null +++ b/kernel/libsepol/tests/test-linker-cond-map.h @@ -0,0 +1,29 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_LINKER_COND_MAP_H__ +#define __TEST_LINKER_COND_MAP_H__ + +#include + +extern void base_cond_tests(policydb_t * base); +extern void module_cond_tests(policydb_t * base); + +#endif diff --git a/kernel/libsepol/tests/test-linker-roles.c b/kernel/libsepol/tests/test-linker-roles.c new file mode 100644 index 00000000..2b17dffd --- /dev/null +++ b/kernel/libsepol/tests/test-linker-roles.c @@ -0,0 +1,204 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-linker-roles.h" +#include "parse_util.h" +#include "helpers.h" +#include "test-common.h" + +#include +#include + +#include +#include + +/* Tests for roles: + * Test for each of these for + * - role in appropriate symtab (global and decl) + * - datum in the decl symtab has correct type_set + * - scope datum has correct decl ids + * - dominates bitmap is correct + * Tests: + * - role in base, no modules + * - role in base optional, no modules + * - role a in base, b in module + * - role a in base and module (additive) + * - role a in base and 2 module + * - role a in base optional, b in module + * - role a in base, b in module optional + * - role a in base optional, b in module optional + * - role a in base optional and module + * - role a in base and module optional + * - role a in base optional and module optional + * - role a in base optional and 2 modules + * - role a and b in base, b dom a, are types correct (TODO) + */ + +/* this simply tests whether the passed in role only has its own + * value in its dominates ebitmap */ +static void only_dominates_self(policydb_t * p, role_datum_t * role) +{ + ebitmap_node_t *tnode; + unsigned int i; + int found = 0; + + ebitmap_for_each_positive_bit(&role->dominates, tnode, i) { + found++; + CU_ASSERT(i == role->s.value - 1); + } + CU_ASSERT(found == 1); +} + +void base_role_tests(policydb_t * base) +{ + avrule_decl_t *decl; + role_datum_t *role; + unsigned int decls[2]; + const char *types[2]; + + /* These tests look at roles in the base only, the desire is to ensure that + * roles are not destroyed or otherwise removed during the link process */ + + /**** test for g_b_role_1 in base and decl 1 (global) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_role_1", SYM_ROLES, SCOPE_DECL, decls, 1); + /* make sure it has the correct type set (g_b_type_1, no negset, no flags) */ + types[0] = "g_b_type_1"; + role = test_role_type_set(base, "g_b_role_1", NULL, types, 1, 0); + /* This role should only dominate itself */ + only_dominates_self(base, role); + + /**** test for o1_b_role_1 in optional (decl 2) ****/ + decl = test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_b"); + decls[0] = decl->decl_id; + test_sym_presence(base, "o1_b_role_1", SYM_ROLES, SCOPE_DECL, decls, 1); + /* make sure it has the correct type set (o1_b_type_1, no negset, no flags) */ + types[0] = "o1_b_type_1"; + role = test_role_type_set(base, "o1_b_role_1", decl, types, 1, 0); + /* and only dominates itself */ + only_dominates_self(base, role); +} + +void module_role_tests(policydb_t * base) +{ + role_datum_t *role; + avrule_decl_t *decl; + unsigned int decls[3]; + const char *types[3]; + + /* These tests are run when the base is linked with 2 modules, + * They should test whether the roles get copied correctly from the + * modules into the base */ + + /**** test for role in module 1 (global) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + test_sym_presence(base, "g_m1_role_1", SYM_ROLES, SCOPE_DECL, decls, 1); + /* make sure it has the correct type set (g_m1_type_1, no negset, no flags) */ + types[0] = "g_m1_type_1"; + role = test_role_type_set(base, "g_m1_role_1", NULL, types, 1, 0); + /* and only dominates itself */ + only_dominates_self(base, role); + + /**** test for role in module 1 (optional) ****/ + decl = test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_m1"); + decls[0] = decl->decl_id; + test_sym_presence(base, "o1_m1_role_1", SYM_ROLES, SCOPE_DECL, decls, 1); + /* make sure it has the correct type set (o1_m1_type_1, no negset, no flags) */ + types[0] = "o1_m1_type_1"; + role = test_role_type_set(base, "o1_m1_role_1", decl, types, 1, 0); + /* and only dominates itself */ + only_dominates_self(base, role); + + /* These test whether the type sets are copied to the right place and + * correctly unioned when they should be */ + + /**** test for type added to base role in module 1 (global) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_role_2", SYM_ROLES, SCOPE_DECL, decls, 1); + /* make sure it has the correct type set (g_m1_type_1, no negset, no flags) */ + types[0] = "g_b_type_2"; /* added in base when declared */ + types[1] = "g_m1_type_1"; /* added in module */ + role = test_role_type_set(base, "g_b_role_2", NULL, types, 2, 0); + /* and only dominates itself */ + only_dominates_self(base, role); + + /**** test for type added to base role in module 1 & 2 (global) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + decls[1] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + decls[2] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m2"))->decl_id; + test_sym_presence(base, "g_b_role_3", SYM_ROLES, SCOPE_DECL, decls, 3); + /* make sure it has the correct type set (g_b_type_2, g_m1_type_2, g_m2_type_2, no negset, no flags) */ + types[0] = "g_b_type_2"; /* added in base when declared */ + types[1] = "g_m1_type_2"; /* added in module 1 */ + types[2] = "g_m2_type_2"; /* added in module 2 */ + role = test_role_type_set(base, "g_b_role_3", NULL, types, 3, 0); + /* and only dominates itself */ + only_dominates_self(base, role); + + /**** test for role in base optional and module 1 (additive) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_b"))->decl_id; + decls[1] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + test_sym_presence(base, "o1_b_role_2", SYM_ROLES, SCOPE_DECL, decls, 2); + /* this one will have 2 type sets, one in the global symtab and one in the base optional 1 */ + types[0] = "g_m1_type_1"; + role = test_role_type_set(base, "o1_b_role_2", NULL, types, 1, 0); + types[0] = "o1_b_type_1"; + role = test_role_type_set(base, "o1_b_role_2", test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_b"), types, 1, 0); + /* and only dominates itself */ + only_dominates_self(base, role); + + /**** test for role in base and module 1 optional (additive) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + decls[1] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o2_m1"))->decl_id; + test_sym_presence(base, "g_b_role_4", SYM_ROLES, SCOPE_DECL, decls, 2); + /* this one will have 2 type sets, one in the global symtab and one in the base optional 1 */ + types[0] = "g_b_type_2"; + role = test_role_type_set(base, "g_b_role_4", NULL, types, 1, 0); + types[0] = "g_m1_type_2"; + role = test_role_type_set(base, "g_b_role_4", test_find_decl_by_sym(base, SYM_TYPES, "tag_o2_m1"), types, 1, 0); + /* and only dominates itself */ + only_dominates_self(base, role); + + /**** test for role in base and module 1 optional (additive) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o3_b"))->decl_id; + decls[1] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o3_m1"))->decl_id; + test_sym_presence(base, "o3_b_role_1", SYM_ROLES, SCOPE_DECL, decls, 2); + /* this one will have 2 type sets, one in the 3rd base optional and one in the 3rd module optional */ + types[0] = "o3_b_type_1"; + role = test_role_type_set(base, "o3_b_role_1", test_find_decl_by_sym(base, SYM_TYPES, "tag_o3_b"), types, 1, 0); + types[0] = "o3_m1_type_1"; + role = test_role_type_set(base, "o3_b_role_1", test_find_decl_by_sym(base, SYM_TYPES, "tag_o3_m1"), types, 1, 0); + /* and only dominates itself */ + only_dominates_self(base, role); + + /**** test for role in base and module 1 optional (additive) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o4_b"))->decl_id; + decls[1] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + decls[2] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m2"))->decl_id; + test_sym_presence(base, "o4_b_role_1", SYM_ROLES, SCOPE_DECL, decls, 3); + /* this one will have 2 type sets, one in the global symtab (with both module types) and one in the 4th optional of base */ + types[0] = "g_m1_type_1"; + role = test_role_type_set(base, "o4_b_role_1", test_find_decl_by_sym(base, SYM_TYPES, "tag_o4_b"), types, 1, 0); + types[0] = "g_m2_type_1"; + types[1] = "g_m1_type_2"; + role = test_role_type_set(base, "o4_b_role_1", NULL, types, 2, 0); + /* and only dominates itself */ + only_dominates_self(base, role); +} diff --git a/kernel/libsepol/tests/test-linker-roles.h b/kernel/libsepol/tests/test-linker-roles.h new file mode 100644 index 00000000..f7407dfe --- /dev/null +++ b/kernel/libsepol/tests/test-linker-roles.h @@ -0,0 +1,29 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_LINKER_ROLES_H__ +#define __TEST_LINKER_ROLES_H__ + +#include + +extern void base_role_tests(policydb_t * base); +extern void module_role_tests(policydb_t * base); + +#endif diff --git a/kernel/libsepol/tests/test-linker-types.c b/kernel/libsepol/tests/test-linker-types.c new file mode 100644 index 00000000..048dd422 --- /dev/null +++ b/kernel/libsepol/tests/test-linker-types.c @@ -0,0 +1,318 @@ +/* + * Author: Joshua Brindle + * Chad Sellers + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-linker-types.h" +#include "parse_util.h" +#include "helpers.h" +#include "test-common.h" + +#include +#include + +#include +#include + +/* Tests for types: + * Test for each of these for + * - type in appropriate symtab (global and decl) + * - datum in the decl symtab has correct type bitmap (if attr) + * - primary is set correctly + * - scope datum has correct decl ids + * Tests: + * - type in base, no modules + * - type in base optional, no modules + * - type a in base, b in module + * - type a in base optional, b in module + * - type a in base, b in module optional + * - type a in base optional, b in module optional + * - attr in base, no modules + * - attr in base optional, no modules + * - attr a in base, b in module + * - attr a in base optional, b in module + * - attr a in base, b in module optional + * - attr a in base optional, b in module optional + * - attr a declared in base, added to in module + * - attr a declared in base, added to in module optional + * - attr a declared in base, added to in 2 modules + * - attr a declared in base, added to in 2 modules (optional and global) + * - attr a declared in base optional, added to in module + * - attr a declared in base optional, added to in module optional + * - attr a added to in base optional, declared in module + * - attr a added to in base optional, declared in module optional + * - attr a added to in base optional, declared in module, added to in other module + * - attr a added to in base optional, declared in module optional, added to in other module + * - attr a added to in base optional, declared in module , added to in other module optional + * - attr a added to in base optional, declared in module optional, added to in other module optional + * - alias in base of primary type in base, no modules + * - alias in base optional of primary type in base, no modules + * - alias in base optional of primary type in base optional + * - alias in module of primary type in base + * - alias in module optional of primary type in base + * - alias in module optional of primary type in base optional + * - alias in module of primary type in module + * - alias in module optional of primary type in module + * - alias in module optional of primary type in module optional + * - alias a in base, b in module, primary type in base + * - alias a in base, b in module, primary type in module + * - alias a in base optional, b in module, primary type in base + * - alias a in base optional, b in module, primary type in module + * - alias a in base, b in module optional, primary type in base + * - alias a in base, b in module optional, primary type in module + * - alias a in base optional, b in module optional, primary type in base + * - alias a in base optional, b in module optional, primary type in module + * - alias a in base, required in module, primary type in base + * - alias a in base, required in base optional, primary type in base + * - alias a in base, required in module optional, primary type in base + * - alias a in module, required in base optional, primary type in base + * - alias a in module, required in module optional, primary type in base + * - alias a in base optional, required in module, primary type in base + * - alias a in base optional, required in different base optional, primary type in base + * - alias a in base optional, required in module optional, primary type in base + * - alias a in module optional, required in base optional, primary type in base + * - alias a in module optional, required in module optional, primary type in base + * - alias a in module, required in base optional, primary type in module + * - alias a in module, required in module optional, primary type in module + * - alias a in base optional, required in module, primary type in module + * - alias a in base optional, required in different base optional, primary type in module + * - alias a in base optional, required in module optional, primary type in module + * - alias a in module optional, required in base optional, primary type in module + * - alias a in module optional, required in module optional, primary type in module + */ + +/* Don't pass in decls from global blocks since symbols aren't stored in their symtab */ +static void test_type_datum(policydb_t * p, const char *id, unsigned int *decls, int len, unsigned int primary) +{ + int i; + unsigned int value; + type_datum_t *type; + + /* just test the type datums for each decl to see if it is what we expect */ + type = hashtab_search(p->p_types.table, id); + + CU_ASSERT_FATAL(type != NULL); + CU_ASSERT(type->primary == primary); + CU_ASSERT(type->flavor == TYPE_TYPE); + + value = type->s.value; + + for (i = 0; i < len; i++) { + type = hashtab_search(p->decl_val_to_struct[decls[i] - 1]->p_types.table, id); + CU_ASSERT_FATAL(type != NULL); + CU_ASSERT(type->primary == primary); + CU_ASSERT(type->flavor == TYPE_TYPE); + CU_ASSERT(type->s.value == value); + } + +} + +void base_type_tests(policydb_t * base) +{ + unsigned int decls[2]; + const char *types[2]; + + /* These tests look at types in the base only, the desire is to ensure that + * types are not destroyed or otherwise removed during the link process. + * if this happens these tests won't work anyway since we are using types to + * mark blocks */ + + /**** test for g_b_type_1 in base and decl 1 (global) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_type_1", SYM_TYPES, SCOPE_DECL, decls, 1); + test_type_datum(base, "g_b_type_1", NULL, 0, 1); + /* this attr is in the same decl as the type */ + test_sym_presence(base, "g_b_attr_1", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "g_b_type_1"; + test_attr_types(base, "g_b_attr_1", NULL, types, 1); + + /**** test for o1_b_type_1 in optional (decl 2) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_b"))->decl_id; + test_sym_presence(base, "o1_b_type_1", SYM_TYPES, SCOPE_DECL, decls, 1); + test_type_datum(base, "o1_b_type_1", NULL, 0, 1); + /* this attr is in the same decl as the type */ + test_sym_presence(base, "o1_b_attr_1", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "o1_b_type_1"; + test_attr_types(base, "o1_b_attr_1", base->decl_val_to_struct[decls[0] - 1], types, 1); + + /* tests for aliases */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_alias_1", SYM_TYPES, SCOPE_DECL, decls, 1); + test_alias_datum(base, "g_b_alias_1", "g_b_type_3", 1, 0); + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o6_b"))->decl_id; + test_sym_presence(base, "g_b_alias_2", SYM_TYPES, SCOPE_DECL, decls, 1); + test_alias_datum(base, "g_b_alias_2", "g_b_type_3", 1, 0); + +} + +void module_type_tests(policydb_t * base) +{ + unsigned int decls[2]; + const char *types[2]; + avrule_decl_t *d; + + /* These tests look at types that were copied from modules or attributes + * that were modified and declared in modules and base. These apply to + * declarations and modifications in and out of optionals. These tests + * should ensure that types and attributes are correctly copied from modules + * and that attribute type sets are correctly copied and mapped. */ + + /* note: scope for attributes is currently smashed if the attribute is declared + * somewhere so the scope test only looks at global, the type bitmap test looks + * at the appropriate decl symtab */ + + /* test for type in module 1 (global) */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + test_sym_presence(base, "g_m1_type_1", SYM_TYPES, SCOPE_DECL, decls, 1); + test_type_datum(base, "g_m1_type_1", NULL, 0, 1); + /* attr has is in the same decl as the above type */ + test_sym_presence(base, "g_m1_attr_1", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "g_m1_type_1"; + types[1] = "g_m1_type_2"; + test_attr_types(base, "g_m1_attr_1", NULL, types, 2); + + /* test for type in module 1 (optional) */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_m1"))->decl_id; + test_sym_presence(base, "o1_m1_type_1", SYM_TYPES, SCOPE_DECL, decls, 1); + test_type_datum(base, "o1_m1_type_1", NULL, 0, 1); + /* attr has is in the same decl as the above type */ + test_sym_presence(base, "o1_m1_attr_1", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "o1_m1_type_2"; + test_attr_types(base, "o1_m1_attr_1", base->decl_val_to_struct[decls[0] - 1], types, 1); + + /* test for attr declared in base, added to in module (global). + * Since these are both global it'll be merged in the main symtab */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_attr_3", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "g_m1_type_3"; + test_attr_types(base, "g_b_attr_3", NULL, types, 1); + + /* test for attr declared in base, added to in module (optional). */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_attr_4", SYM_TYPES, SCOPE_DECL, decls, 1); + + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_m1"))->decl_id; + types[0] = "o1_m1_type_3"; + test_attr_types(base, "g_b_attr_4", base->decl_val_to_struct[decls[0] - 1], types, 1); + + /* test for attr declared in base, added to in 2 modules (global). (merged in main symtab) */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_attr_5", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "g_m1_type_4"; + types[1] = "g_m2_type_4"; + test_attr_types(base, "g_b_attr_5", NULL, types, 2); + + /* test for attr declared in base, added to in 2 modules (optional/global). */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; + test_sym_presence(base, "g_b_attr_6", SYM_TYPES, SCOPE_DECL, decls, 1); + /* module 2 was global to its type is in main symtab */ + types[0] = "g_m2_type_5"; + test_attr_types(base, "g_b_attr_6", NULL, types, 1); + d = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o3_m1")); + types[0] = "o3_m1_type_2"; + test_attr_types(base, "g_b_attr_6", d, types, 1); + + /* test for attr declared in base optional, added to in module (global). */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o4_b"))->decl_id; + test_sym_presence(base, "o4_b_attr_1", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "g_m1_type_5"; + test_attr_types(base, "o4_b_attr_1", NULL, types, 1); + + /* test for attr declared in base optional, added to in module (optional). */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_b"))->decl_id; + test_sym_presence(base, "o1_b_attr_2", SYM_TYPES, SCOPE_DECL, decls, 1); + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_m1"); + types[0] = "o1_m1_type_5"; + test_attr_types(base, "o1_b_attr_2", d, types, 1); + + /* test for attr declared in module, added to in base optional */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + test_sym_presence(base, "g_m1_attr_2", SYM_TYPES, SCOPE_DECL, decls, 1); + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o1_b"); + types[0] = "o1_b_type_2"; + test_attr_types(base, "g_m1_attr_2", d, types, 1); + + /* test for attr declared in module optional, added to in base optional */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_o3_m1"))->decl_id; + test_sym_presence(base, "o3_m1_attr_1", SYM_TYPES, SCOPE_DECL, decls, 1); + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o4_b"); + types[0] = "o4_b_type_1"; + test_attr_types(base, "o3_m1_attr_1", d, types, 1); + + /* attr a added to in base optional, declared/added to in module, added to in other module */ + /* first the module declare/add and module 2 add (since its global it'll be in the main symtab */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + test_sym_presence(base, "g_m1_attr_3", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "g_m1_type_6"; + types[1] = "g_m2_type_3"; + test_attr_types(base, "g_m1_attr_3", NULL, types, 2); + /* base add */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o4_b"); + types[0] = "o4_b_type_2"; + test_attr_types(base, "g_m1_attr_3", d, types, 1); + + /* attr a added to in base optional, declared/added in module optional, added to in other module */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o3_m1"); + decls[0] = d->decl_id; + test_sym_presence(base, "o3_m1_attr_2", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "o3_m1_type_3"; + test_attr_types(base, "o3_m1_attr_2", d, types, 1); + /* module 2's type will be in the main symtab */ + types[0] = "g_m2_type_6"; + test_attr_types(base, "o3_m1_attr_2", NULL, types, 1); + /* base add */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o2_b"); + types[0] = "o2_b_type_1"; + test_attr_types(base, "o3_m1_attr_2", d, types, 1); + + /* attr a added to in base optional, declared/added in module , added to in other module optional */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + test_sym_presence(base, "g_m1_attr_4", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "g_m1_type_7"; + test_attr_types(base, "g_m1_attr_4", NULL, types, 1); + /* module 2 */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o2_m2"); + types[0] = "o2_m2_type_1"; + test_attr_types(base, "g_m1_attr_4", d, types, 1); + /* base add */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o5_b"); + types[0] = "o5_b_type_1"; + test_attr_types(base, "g_m1_attr_4", d, types, 1); + + /* attr a added to in base optional, declared/added in module optional, added to in other module optional */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o4_m1"); + decls[0] = d->decl_id; + test_sym_presence(base, "o4_m1_attr_1", SYM_TYPES, SCOPE_DECL, decls, 1); + types[0] = "o4_m1_type_1"; + test_attr_types(base, "o4_m1_attr_1", d, types, 1); + /* module 2 */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o2_m2"); + types[0] = "o2_m2_type_2"; + test_attr_types(base, "o4_m1_attr_1", d, types, 1); + /* base add */ + d = test_find_decl_by_sym(base, SYM_TYPES, "tag_o5_b"); + types[0] = "o5_b_type_2"; + test_attr_types(base, "o4_m1_attr_1", d, types, 1); + + /* tests for aliases */ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; + test_sym_presence(base, "g_m_alias_1", SYM_TYPES, SCOPE_DECL, decls, 1); + test_alias_datum(base, "g_m_alias_1", "g_b_type_3", 1, 0); + +} diff --git a/kernel/libsepol/tests/test-linker-types.h b/kernel/libsepol/tests/test-linker-types.h new file mode 100644 index 00000000..acad5e0e --- /dev/null +++ b/kernel/libsepol/tests/test-linker-types.h @@ -0,0 +1,29 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_LINKER_TYPES_H__ +#define __TEST_LINKER_TYPES_H__ + +#include + +extern void base_type_tests(policydb_t * base); +extern void module_type_tests(policydb_t * base); + +#endif diff --git a/kernel/libsepol/tests/test-linker.c b/kernel/libsepol/tests/test-linker.c new file mode 100644 index 00000000..8d8e949e --- /dev/null +++ b/kernel/libsepol/tests/test-linker.c @@ -0,0 +1,154 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This is where the linker tests should go, including: + * - check role, type, bool, user, attr mapping + * - check for properly enabled optional + * - check for properly disabled optional + * - check for non-optional disabled blocks + * - properly add symbols declared in optionals + */ + +#include "test-linker.h" +#include "parse_util.h" +#include "helpers.h" +#include "test-common.h" +#include "test-linker-roles.h" +#include "test-linker-types.h" +#include "test-linker-cond-map.h" + +#include +#include +#include +#include +#include +#include + +#define NUM_MODS 2 +#define NUM_POLICIES NUM_MODS+1 + +#define BASEMOD NUM_MODS +const char *policies[NUM_POLICIES] = { + "module1.conf", + "module2.conf", + "small-base.conf", +}; + +static policydb_t basenomods; +static policydb_t linkedbase; +static policydb_t *modules[NUM_MODS]; +extern int mls; + +int linker_test_init(void) +{ + int i; + + if (test_load_policy(&linkedbase, POLICY_BASE, mls, "test-linker", policies[BASEMOD])) + return -1; + + if (test_load_policy(&basenomods, POLICY_BASE, mls, "test-linker", policies[BASEMOD])) + return -1; + + for (i = 0; i < NUM_MODS; i++) { + + modules[i] = calloc(1, sizeof(*modules[i])); + if (!modules[i]) { + fprintf(stderr, "out of memory!\n"); + return -1; + } + + if (test_load_policy(modules[i], POLICY_MOD, mls, "test-linker", policies[i])) + return -1; + + } + + if (link_modules(NULL, &linkedbase, modules, NUM_MODS, 0)) { + fprintf(stderr, "link modules failed\n"); + return -1; + } + + if (link_modules(NULL, &basenomods, NULL, 0, 0)) { + fprintf(stderr, "link modules failed\n"); + return -1; + } + + return 0; +} + +int linker_test_cleanup(void) +{ + int i; + + ksu_policydb_destroy(&basenomods); + ksu_policydb_destroy(&linkedbase); + + for (i = 0; i < NUM_MODS; i++) { + ksu_policydb_destroy(modules[i]); + free(modules[i]); + } + return 0; +} + +static void test_linker_indexes(void) +{ + test_policydb_indexes(&linkedbase); +} + +static void test_linker_roles(void) +{ + base_role_tests(&basenomods); + base_role_tests(&linkedbase); + module_role_tests(&linkedbase); +} + +static void test_linker_types(void) +{ + base_type_tests(&basenomods); + base_type_tests(&linkedbase); + module_type_tests(&linkedbase); +} + +static void test_linker_cond(void) +{ + base_cond_tests(&basenomods); + base_cond_tests(&linkedbase); + module_cond_tests(&linkedbase); +} + +int linker_add_tests(CU_pSuite suite) +{ + if (NULL == CU_add_test(suite, "linker_indexes", test_linker_indexes)) { + CU_cleanup_registry(); + return CU_get_error(); + } + if (NULL == CU_add_test(suite, "linker_types", test_linker_types)) { + CU_cleanup_registry(); + return CU_get_error(); + } + if (NULL == CU_add_test(suite, "linker_roles", test_linker_roles)) { + CU_cleanup_registry(); + return CU_get_error(); + } + if (NULL == CU_add_test(suite, "linker_cond", test_linker_cond)) { + CU_cleanup_registry(); + return CU_get_error(); + } + return 0; +} diff --git a/kernel/libsepol/tests/test-linker.h b/kernel/libsepol/tests/test-linker.h new file mode 100644 index 00000000..16339a08 --- /dev/null +++ b/kernel/libsepol/tests/test-linker.h @@ -0,0 +1,30 @@ +/* + * Author: Joshua Brindle + * + * Copyright (C) 2006 Tresys Technology, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TEST_LINKER_H__ +#define __TEST_LINKER_H__ + +#include + +int linker_test_init(void); +int linker_test_cleanup(void); +int linker_add_tests(CU_pSuite suite); + +#endif diff --git a/kernel/libsepol/utils/Makefile b/kernel/libsepol/utils/Makefile new file mode 100644 index 00000000..31932c11 --- /dev/null +++ b/kernel/libsepol/utils/Makefile @@ -0,0 +1,25 @@ +# Installation directories. +PREFIX ?= /usr +BINDIR ?= $(PREFIX)/bin + +CFLAGS ?= -Wall -Werror +override CFLAGS += -I../include +override LDFLAGS += -L../src +override LDLIBS += -lsepol + +TARGETS=$(patsubst %.c,%,$(sort $(wildcard *.c))) + +all: $(TARGETS) + +install: all + -mkdir -p $(DESTDIR)$(BINDIR) + install -m 755 $(TARGETS) $(DESTDIR)$(BINDIR) + +clean: + -rm -f $(TARGETS) *.o + +indent: + ../../scripts/Lindent $(wildcard *.[ch]) + +relabel: + diff --git a/kernel/libsepol/utils/chkcon.c b/kernel/libsepol/utils/chkcon.c new file mode 100644 index 00000000..baa51177 --- /dev/null +++ b/kernel/libsepol/utils/chkcon.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include +#include + +void usage(char*) __attribute__((noreturn)); + +void usage(char *progname) +{ + printf("usage: %s policy context\n", progname); + exit(1); +} + +int main(int argc, char **argv) +{ + FILE *fp; + + if (argc != 3) + usage(argv[0]); + + fp = fopen(argv[1], "r"); + if (!fp) { + fprintf(stderr, "Can't open '%s': %s\n", + argv[1], strerror(errno)); + exit(1); + } + if (sepol_set_policydb_from_file(fp) < 0) { + fprintf(stderr, "Error while processing %s: %s\n", + argv[1], strerror(errno)); + exit(1); + } + fclose(fp); + + if (sepol_check_context(argv[2]) < 0) { + fprintf(stderr, "%s is not valid\n", argv[2]); + exit(1); + } + + printf("%s is valid\n", argv[2]); + exit(0); +} diff --git a/kernel/libsepol/utils/sepol_check_access.c b/kernel/libsepol/utils/sepol_check_access.c new file mode 100644 index 00000000..bd2ea896 --- /dev/null +++ b/kernel/libsepol/utils/sepol_check_access.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include + +#include +#include + + +int main(int argc, char *argv[]) +{ + FILE *fp; + sepol_security_id_t ssid, tsid; + sepol_security_class_t tclass; + const char *permlist; + sepol_access_vector_t av; + struct sepol_av_decision avd; + unsigned int reason; + char *reason_buf; + int i; + + if (argc != 6) { + printf("usage: %s policy source_context target_context class permission[,permission2[,...]]\n", argv[0]); + return 1; + } + + fp = fopen(argv[1], "r"); + if (!fp) { + fprintf(stderr, "Can't open policy %s: %s\n", argv[1], strerror(errno)); + return 1; + } + if (sepol_set_policydb_from_file(fp) < 0) { + fprintf(stderr, "Error while processing policy %s: %s\n", argv[1], strerror(errno)); + fclose(fp); + return 1; + } + fclose(fp); + + if (sepol_context_to_sid(argv[2], strlen(argv[2]), &ssid) < 0) { + fprintf(stderr, "Invalid source context %s\n", argv[2]); + return 1; + } + + if (sepol_context_to_sid(argv[3], strlen(argv[3]), &tsid) < 0) { + fprintf(stderr, "Invalid target context %s\n", argv[3]); + return 1; + } + + if (sepol_string_to_security_class(argv[4], &tclass) < 0) { + fprintf(stderr, "Invalid security class %s\n", argv[4]); + return 1; + } + + permlist = argv[5]; + do { + char *tmp = NULL; + const char *perm; + const char *delim = strchr(permlist, ','); + + if (delim) { + tmp = strndup(permlist, delim - permlist); + if (!tmp) { + fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno)); + return 1; + } + } + + perm = tmp ? tmp : permlist; + + if (sepol_string_to_av_perm(tclass, perm, &av) < 0) { + fprintf(stderr, "Invalid permission %s for security class %s: %s\n", perm, argv[4], strerror(errno)); + free(tmp); + return 1; + } + + free(tmp); + + permlist = strchr(permlist, ','); + } while (permlist++); + + if (av == 0) { + fprintf(stderr, "Empty permission set computed from %s\n", argv[5]); + return 1; + } + + if (sepol_compute_av_reason_buffer(ssid, tsid, tclass, av, &avd, &reason, &reason_buf, 0) < 0) { + fprintf(stderr, "Failed to compute av decision: %s\n", strerror(errno)); + return 1; + } + + if ((avd.allowed & av) == av) { + printf("requested permission %s allowed\n", argv[5]); + free(reason_buf); + return 0; + } + + printf("requested permission %s denied by ", argv[5]); + i = 0; + if (reason & SEPOL_COMPUTEAV_TE) { + printf("te-rule"); + i++; + } + if (reason & SEPOL_COMPUTEAV_CONS) { + if (i > 0) + printf(", "); + printf("constraint"); + i++; + } + if (reason & SEPOL_COMPUTEAV_RBAC) { + if (i > 0) + printf(", "); + printf("transition-constraint"); + i++; + } + if (reason & SEPOL_COMPUTEAV_BOUNDS) { + if (i > 0) + printf(", "); + printf("type-bound"); + //i++; + } + + if ((reason & SEPOL_COMPUTEAV_CONS) && reason_buf) + printf("; reason:\n%s", reason_buf); + + free(reason_buf); + + printf("\n"); + + return 7; +} diff --git a/kernel/libsepol/utils/sepol_compute_av.c b/kernel/libsepol/utils/sepol_compute_av.c new file mode 100644 index 00000000..d64dc31d --- /dev/null +++ b/kernel/libsepol/utils/sepol_compute_av.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#include +#include + + +int main(int argc, char *argv[]) +{ + FILE *fp; + sepol_security_id_t ssid, tsid; + sepol_security_class_t tclass; + struct sepol_av_decision avd; + int rc; + + if (argc != 5) { + printf("usage: %s policy scontext tcontext tclass\n", argv[0]); + return 1; + } + + fp = fopen(argv[1], "r"); + if (!fp) { + fprintf(stderr, "Can't open policy %s: %s\n", argv[1], strerror(errno)); + return 1; + } + if (sepol_set_policydb_from_file(fp) < 0) { + fprintf(stderr, "Error while processing policy %s: %s\n", argv[1], strerror(errno)); + fclose(fp); + return 1; + } + fclose(fp); + + if (sepol_context_to_sid(argv[2], strlen(argv[2]), &ssid) < 0) { + fprintf(stderr, "Invalid source context %s\n", argv[2]); + return 1; + } + + if (sepol_context_to_sid(argv[3], strlen(argv[3]), &tsid) < 0) { + fprintf(stderr, "Invalid target context %s\n", argv[3]); + return 1; + } + + if (sepol_string_to_security_class(argv[4], &tclass) < 0) { + fprintf(stderr, "Invalid security class %s\n", argv[4]); + return 1; + } + + rc = sepol_compute_av(ssid, tsid, tclass, 0, &avd); + switch (rc) { + case 0: + printf("allowed: %s\n", sepol_av_perm_to_string(tclass, avd.allowed)); + printf("decided: %s\n", sepol_av_perm_to_string(tclass, avd.decided)); + printf("auditallow: %s\n", sepol_av_perm_to_string(tclass, avd.auditallow)); + printf("auditdeny: %s\n", sepol_av_perm_to_string(tclass, avd.auditdeny)); + break; + case -EINVAL: + printf("Invalid request\n"); + break; + default: + printf("Failed to compute av decision: %d\n", rc); + } + + return rc != 0; +} diff --git a/kernel/libsepol/utils/sepol_compute_member.c b/kernel/libsepol/utils/sepol_compute_member.c new file mode 100644 index 00000000..69481055 --- /dev/null +++ b/kernel/libsepol/utils/sepol_compute_member.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include +#include + + +int main(int argc, char *argv[]) +{ + FILE *fp; + sepol_security_id_t ssid, tsid, out_sid; + sepol_security_class_t tclass; + char *context; + size_t context_len; + + if (argc != 5) { + printf("usage: %s policy scontext tcontext tclass\n", argv[0]); + return 1; + } + + fp = fopen(argv[1], "r"); + if (!fp) { + fprintf(stderr, "Can't open policy %s: %s\n", argv[1], strerror(errno)); + return 1; + } + if (sepol_set_policydb_from_file(fp) < 0) { + fprintf(stderr, "Error while processing policy %s: %s\n", argv[1], strerror(errno)); + fclose(fp); + return 1; + } + fclose(fp); + + if (sepol_context_to_sid(argv[2], strlen(argv[2]), &ssid) < 0) { + fprintf(stderr, "Invalid source context %s\n", argv[2]); + return 1; + } + + if (sepol_context_to_sid(argv[3], strlen(argv[3]), &tsid) < 0) { + fprintf(stderr, "Invalid target context %s\n", argv[3]); + return 1; + } + + if (sepol_string_to_security_class(argv[4], &tclass) < 0) { + fprintf(stderr, "Invalid security class %s\n", argv[4]); + return 1; + } + + if (sepol_member_sid(ssid, tsid, tclass, &out_sid) < 0) { + fprintf(stderr, "Failed to compute member sid: %s\n", strerror(errno)); + return 1; + } + + if (sepol_sid_to_context(out_sid, &context, &context_len) < 0) { + fprintf(stderr, "Failed to convert sid %u: %s\n", out_sid, strerror(errno)); + return 1; + } + + printf("%s\n", context); + free(context); + + return 0; +} diff --git a/kernel/libsepol/utils/sepol_compute_relabel.c b/kernel/libsepol/utils/sepol_compute_relabel.c new file mode 100644 index 00000000..24657530 --- /dev/null +++ b/kernel/libsepol/utils/sepol_compute_relabel.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include +#include + + +int main(int argc, char *argv[]) +{ + FILE *fp; + sepol_security_id_t ssid, tsid, out_sid; + sepol_security_class_t tclass; + char *context; + size_t context_len; + + if (argc != 5) { + printf("usage: %s policy scontext tcontext tclass\n", argv[0]); + return 1; + } + + fp = fopen(argv[1], "r"); + if (!fp) { + fprintf(stderr, "Can't open policy %s: %s\n", argv[1], strerror(errno)); + return 1; + } + if (sepol_set_policydb_from_file(fp) < 0) { + fprintf(stderr, "Error while processing policy %s: %s\n", argv[1], strerror(errno)); + fclose(fp); + return 1; + } + fclose(fp); + + if (sepol_context_to_sid(argv[2], strlen(argv[2]), &ssid) < 0) { + fprintf(stderr, "Invalid source context %s\n", argv[2]); + return 1; + } + + if (sepol_context_to_sid(argv[3], strlen(argv[3]), &tsid) < 0) { + fprintf(stderr, "Invalid target context %s\n", argv[3]); + return 1; + } + + if (sepol_string_to_security_class(argv[4], &tclass) < 0) { + fprintf(stderr, "Invalid security class %s\n", argv[4]); + return 1; + } + + if (sepol_change_sid(ssid, tsid, tclass, &out_sid) < 0) { + fprintf(stderr, "Failed to compute changed sid: %s\n", strerror(errno)); + return 1; + } + + if (sepol_sid_to_context(out_sid, &context, &context_len) < 0) { + fprintf(stderr, "Failed to convert sid %u: %s\n", out_sid, strerror(errno)); + return 1; + } + + printf("%s\n", context); + free(context); + + return 0; +} diff --git a/kernel/libsepol/utils/sepol_validate_transition.c b/kernel/libsepol/utils/sepol_validate_transition.c new file mode 100644 index 00000000..621b5e22 --- /dev/null +++ b/kernel/libsepol/utils/sepol_validate_transition.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +#include +#include + + +int main(int argc, char *argv[]) +{ + FILE *fp; + sepol_security_id_t oldsid, newsid, tasksid; + sepol_security_class_t tclass; + char *reason = NULL; + int ret; + + if (argc != 6) { + printf("usage: %s policy oldcontext newcontext tclass taskcontext\n", argv[0]); + return 1; + } + + fp = fopen(argv[1], "r"); + if (!fp) { + fprintf(stderr, "Can't open policy %s: %s\n", argv[1], strerror(errno)); + return 1; + } + if (sepol_set_policydb_from_file(fp) < 0) { + fprintf(stderr, "Error while processing policy %s: %s\n", argv[1], strerror(errno)); + fclose(fp); + return 1; + } + fclose(fp); + + if (sepol_context_to_sid(argv[2], strlen(argv[2]), &oldsid) < 0) { + fprintf(stderr, "Invalid old context %s\n", argv[2]); + return 1; + } + + if (sepol_context_to_sid(argv[3], strlen(argv[3]), &newsid) < 0) { + fprintf(stderr, "Invalid new context %s\n", argv[3]); + return 1; + } + + if (sepol_string_to_security_class(argv[4], &tclass) < 0) { + fprintf(stderr, "Invalid security class %s\n", argv[4]); + return 1; + } + + if (sepol_context_to_sid(argv[5], strlen(argv[5]), &tasksid) < 0) { + fprintf(stderr, "Invalid task context %s\n", argv[5]); + return 1; + } + + ret = sepol_validate_transition_reason_buffer(oldsid, newsid, tasksid, tclass, &reason, SHOW_GRANTED); + switch (ret) { + case 0: + printf("allowed\n"); + ret = 0; + break; + case -EPERM: + printf("denied\n"); + printf("%s\n", reason ? reason : "unknown - possible BUG()"); + ret = 7; + break; + default: + printf("sepol_validate_transition_reason_buffer returned %d errno: %s\n", ret, strerror(errno)); + ret = 1; + } + + free(reason); + + return ret; +}