pax_global_header00006660000000000000000000000064124637057220014522gustar00rootroot0000000000000052 comment=f0c9966f881211dcde89cfcad93f0360a71f959a libsepol-2.4/000077500000000000000000000000001246370572200132005ustar00rootroot00000000000000libsepol-2.4/.gitignore000066400000000000000000000000321246370572200151630ustar00rootroot00000000000000utils/chkcon libsepol.map libsepol-2.4/Android.mk000066400000000000000000000040651246370572200151160ustar00rootroot00000000000000LOCAL_PATH:= $(call my-dir) common_src_files := \ src/assertion.c \ src/avrule_block.c \ src/avtab.c \ src/boolean_record.c \ src/booleans.c \ src/conditional.c \ src/constraint.c \ src/context.c \ src/context_record.c \ src/debug.c \ src/ebitmap.c \ src/expand.c \ src/genbools.c \ src/genusers.c \ src/handle.c \ src/hashtab.c \ src/hierarchy.c \ src/iface_record.c \ src/interfaces.c \ src/link.c \ src/mls.c \ src/module.c \ src/node_record.c \ src/nodes.c \ src/polcaps.c \ src/policydb.c \ src/policydb_convert.c \ src/policydb_public.c \ src/port_record.c \ src/ports.c \ src/roles.c \ src/services.c \ src/sidtab.c \ src/symtab.c \ src/user_record.c \ src/users.c \ src/util.c \ src/write.c common_cflags := \ -Wall -W -Wundef \ -Wshadow -Wmissing-noreturn \ -Wmissing-format-attribute ifeq ($(HOST_OS), darwin) common_cflags += -DDARWIN endif common_includes := \ $(LOCAL_PATH)/include/ \ $(LOCAL_PATH)/src/ ## # libsepol.so # include $(CLEAR_VARS) LOCAL_MODULE := libsepol LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) LOCAL_CFLAGS := $(common_cflags) LOCAL_SRC_FILES := $(common_src_files) LOCAL_MODULE_CLASS := SHARED_LIBRARIES include $(BUILD_HOST_SHARED_LIBRARY) ## # libsepol.a # include $(CLEAR_VARS) LOCAL_MODULE := libsepol LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) LOCAL_CFLAGS := $(common_cflags) LOCAL_SRC_FILES := $(common_src_files) LOCAL_MODULE_CLASS := STATIC_LIBRARIES include $(BUILD_HOST_STATIC_LIBRARY) ## # chkcon # include $(CLEAR_VARS) LOCAL_MODULE := chkcon LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) LOCAL_CFLAGS := $(common_cflags) LOCAL_SRC_FILES := utils/chkcon.c LOCAL_SHARED_LIBRARIES := libsepol LOCAL_MODULE_CLASS := EXECUTABLES include $(BUILD_HOST_EXECUTABLE) include $(CLEAR_VARS) LOCAL_MODULE := libsepol LOCAL_MODULE_TAGES := optional LOCAL_C_INCLUDES := $(common_includes) LOCAL_CFLAGS := $(common_cflags) LOCAL_SRC_FILES := $(common_src_files) LOCAL_MODULE_CLASS := STATIC_LIBRARIES include $(BUILD_STATIC_LIBRARY) libsepol-2.4/COPYING000066400000000000000000000635001246370572200142370ustar00rootroot00000000000000 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! libsepol-2.4/ChangeLog000066400000000000000000000630071246370572200147600ustar00rootroot000000000000002.4 2015-02-02 * Remove assumption that SHLIBDIR is ../../ relative to LIBDIR, from Steve Lawrence * Fix bugs found by hardened gcc flags, from Nicolas Iooss. * Build CIL into libsepol. libsepol can be built without CIL by setting the DISABLE_CIL flag to 'y', from Steve Lawrence * Add an API function to set target_platform, from Steve Lawrence * Report all neverallow violations, from Stephen Smalley * Improve check_assertions performance through hash tweaks from John Brooks. * Allow libsepol C++ static library on device from Daniel Cashman. 2.3 2014-05-06 * Improve error message for name-based transition conflicts. * Revert libsepol: filename_trans: use some better sorting to compare and merge. * Report source file and line information for neverallow failures. * Fix valgrind errors in constraint_expr_eval_reason from Richard Haines. * Add sepol_validate_transition_reason_buffer function from Richard Haines. 2.2 2013-10-30 * Allow constraint denial cause to be determined from Richard Haines. - Add kernel policy version 29. - Add modular policy version 17. - Add sepol_compute_av_reason_buffer(), sepol_string_to_security_class(), sepol_string_to_av_perm(). * Support overriding Makefile RANLIB from Sven Vermeulen. * Fix man pages from Laurent Bigonville. 2.1.9 2013-02-01 * filename_trans: use some better sorting to compare and merge * coverity fixes * implement default type policy syntax * Fix memory leak issues found by Klocwork 2.1.8 2012-09-13 * fix neverallow checking on attributes * Move context_copy() after switch block in ocontext_copy_*(). * check for missing initial SID labeling statement. * Add always_check_network policy capability * role_fix_callback skips out-of-scope roles during expansion. 2.1.7 2012-06-28 * reserve policycapability for redhat testing of ptrace child * cosmetic changes to make the source easier to read * prepend instead of append to filename_trans list * Android/MacOS X build support 2.1.6 2012-04-23 * allocate enough space to hold filename in trans rules 2.1.5 2012-03-28 * checkpolicy: implement new default labeling behaviors 2.1.4 2011-10-03 * regenerate .pc on VERSION change * Move ebitmap_* functions from mcstrans to libsepol * expand: do filename_trans type comparison on mapped representation 2.1.3 2011-09-15 * Skip writing role attributes for policy.X and * Indicate when boolean is indeed a tunable. * Separate tunable from boolean during compile. * Write and read TUNABLE flags in related * Copy and check the cond_bool_datum_t.flags during link. * Permanently discard disabled branches of tunables in * Skip tunable identifier and cond_node_t in expansion. * Create a new preserve_tunables flag * Preserve tunables when required by semodule program. * setools expects expand_module_avrules to be an exported * tree: default make target to all not 2.1.2 2011-08-03 * Only call role_fix_callback for base.p_roles during expansion. * use mapped role number instead of module role number 2.1.1 2011-08-01 * Minor fix to reading policy with filename transition rules 2.1.0 2011-07-27 * Release, minor version bump 2.0.46 2011-07-25 * Add role attribute support by Harry Ciao 2.0.45 2011-05-02 * Warn if filename_trans rules are dropped by Steve Lawrence. 2.0.44 2011-04-13 * Fixes for new role_transition class field by Eric Paris. * Add libsepol support for filename_trans rules by Eric Paris. 2.0.43 2011-04-11 * Add new class field in role_transition by Harry Ciao. 2.0.42 2010-12-16 * Fix compliation under GCC 4.6 by Justin Mattock 2.0.41 2009-11-18 * Fixed typo in error message from Manoj Srivastava. 2.0.40 2009-10-29 * Add pkgconfig file from Eamon Walsh. 2.0.39 2009-10-14 * Add support for building Xen policies from Paul Nuzzi. 2.0.38 2009-09-01 * Check last offset in the module package against the file size. Reported by Manoj Srivastava for bug filed by Max Kellermann. 2.0.37 2009-07-07 * Add method to check disable dontaudit flag from Christopher Pardy. 2.0.36 2009-03-25 * Fix boolean state smashing from Joshua Brindle. 2.0.35 2009-02-19 * Fix alias field in module format, caused by boundary format change from Caleb Case. 2.0.34 2008-10-09 * Add bounds support from KaiGai Kohei. * Fix invalid aliases bug from Joshua Brindle. 2.0.33 2008-09-29 * Revert patch that removed expand_rule. 2.0.32 2008-07-07 * Allow require then declare in the source policy from Joshua Brindle. 2.0.31 2008-06-13 * Fix mls_semantic_level_expand() to handle a user require w/o MLS information from Stephen Smalley. 2.0.30 2008-06-06 * Fix endianness bug in the handling of network node addresses from Stephen Smalley. Only affects big endian platforms. Bug reported by John Weeks of Sun upon policy mismatch between x86 and sparc. 2.0.29 2008-05-27 * Merge user and role mapping support from Joshua Brindle. 2.0.28 2008-05-05 * Fix mls_level_convert() to gracefully handle an empty user declaration/require from Stephen Smalley. 2.0.27 2008-04-18 * Belatedly merge test for policy downgrade from Todd Miller. 2.0.26 2008-03-24 * Add permissive domain support from Eric Paris. 2.0.25 2008-03-04 * Drop unused ->buffer field from struct policy_file. 2.0.24 2008-03-04 * Add policy_file_init() initalizer for struct policy_file and use it, from Todd C. Miller. 2.0.23 2008-02-28 * Accept "Flask" as an alternate identifier string in kernel policies from Stephen Smalley. 2.0.22 2008-02-28 * Add support for open_perms policy capability from Eric Paris. 2.0.21 2008-02-20 * Fix invalid memory allocation in policydb_index_others() from Jason Tang. 2.0.20 2008-02-04 * Port of Yuichi Nakamura's tune avtab to reduce memory usage patch from the kernel avtab to libsepol from Stephen Smalley. 2.0.19 2008-02-02 * Add support for consuming avrule_blocks during expansion to reduce peak memory usage from Joshua Brindle. 2.0.18 2008-01-02 * Added support for policy capabilities from Todd Miller. 2.0.17 2007-12-21 * Prevent generation of policy.18 with MLS enabled from Todd Miller. 2.0.16 2007-12-07 * print module magic number in hex on mismatch, from Todd Miller. 2.0.15 2007-11-29 * clarify and reduce neverallow error reporting from Stephen Smalley. 2.0.14 2007-11-05 * Reject self aliasing at link time from Stephen Smalley. 2.0.13 2007-11-05 * Allow handle_unknown in base to be overridden by semanage.conf from Stephen Smalley. 2.0.12 2007-10-11 * Fixed bug in require checking from Stephen Smalley. * Added user hierarchy checking from Todd Miller. 2.0.11 2007-09-24 * Pass CFLAGS to CC even on link command, per Dennis Gilmore. 2.0.10 2007-09-18 * Merged support for the handle_unknown policydb flag from Eric Paris. 2.0.9 2007-08-29 * Moved next_entry and put_entry out-of-line to reduce code size from Ulrich Drepper. 2.0.8 2007-08-28 * Fixed module_package_read_offsets bug introduced by the prior patch. 2.0.7 2007-08-23 * Eliminate unaligned accesses from policy reading code from Stephen Smalley. 2.0.6 2007-08-16 * Allow dontaudits to be turned off during policy expansion from Joshua Brindle. 2.0.5 2007-08-01 * Fix sepol_context_clone to handle a NULL context correctly. This happens for e.g. semanage_fcontext_set_con(sh, fcontext, NULL) to set the file context entry to "<>". 2.0.4 2007-06-20 * Merged error handling patch from Eamon Walsh. 2.0.3 2007-04-13 * Merged add boolmap argument to expand_module_avrules() from Chris PeBenito. 2.0.2 2007-03-30 * Merged fix from Karl to remap booleans at expand time to avoid holes in the symbol table. 2.0.1 2007-02-06 * Merged libsepol segfault fix from Stephen Smalley for when sensitivities are required but not present in the base. 2.0.0 2007-02-01 * Merged patch to add errcodes.h to libsepol by Karl MacMillan. 1.16.0 2007-01-18 * Updated version for stable branch. 1.15.3 2006-11-27 * Merged patch to compile wit -fPIC instead of -fpic from Manoj Srivastava to prevent hitting the global offest table limit. Patch changed to include libselinux and libsemanage in addition to libselinux. 1.15.2 2006-10-31 * Merged fix from Karl MacMillan for a segfault when linking non-MLS modules with users in them. 1.15.1 2006-10-24 * Merged fix for version comparison that was preventing range transition rules from being written for a version 5 base policy from Darrel Goeddel. 1.14 2006-10-17 * Updated version for release. 1.12.28 2006-09-28 * Build libsepol's static object files with -fpic 1.12.27 2006-09-28 * Merged mls user and range_transition support in modules from Darrel Goeddel 1.12.26 2006-09-05 * Merged range transition enhancements and user format changes Darrel Goeddel 1.12.25 2006-08-24 * Merged conditionally expand neverallows patch from Jeremy Mowery. * Merged refactor expander patch from Jeremy Mowery. 1.12.24 2006-08-03 * Merged libsepol unit tests from Joshua Brindle. 1.12.23 2006-08-03 * Merged symtab datum patch from Karl MacMillan. 1.12.22 2006-08-03 * Merged netfilter contexts support from Chris PeBenito. 1.12.21 2006-07-28 * Merged helpful hierarchy check errors patch from Joshua Brindle. 1.12.20 2006-07-25 * Merged semodule_deps patch from Karl MacMillan. This adds source module names to the avrule decls. 1.12.19 2006-06-29 * Lindent. 1.12.18 2006-06-26 * Merged optionals in base take 2 patch set from Joshua Brindle. 1.12.17 2006-05-30 * Revert 1.12.16. 1.12.16 2006-05-30 * Merged cleaner fix for bool_ids overflow from Karl MacMillan, replacing the prior patch. 1.12.15 2006-05-30 * Merged fixes for several memory leaks in the error paths during policy read from Serge Hallyn. 1.12.14 2006-05-25 * Fixed bool_ids overflow bug in cond_node_find and cond_copy_list, based on bug report and suggested fix by Cedric Roux. 1.12.13 2006-05-24 * Merged sens_copy_callback, check_role_hierarchy_callback, and node_from_record fixes from Serge Hallyn. 1.12.12 2006-05-22 * Added sepol_policydb_compat_net() interface for testing whether a policy requires the compatibility support for network checks to be enabled in the kernel. 1.12.11 2006-05-17 * Merged patch to initialize sym_val_to_name arrays from Kevin Carr. Reworked to use calloc in the first place, and converted some other malloc/memset pairs to calloc calls. 1.12.10 2006-05-08 * Merged patch to revert role/user decl upgrade from Karl MacMillan. 1.12.9 2006-05-08 * Dropped tests from all Makefile target. 1.12.8 2006-05-05 * Merged fix warnings patch from Karl MacMillan. 1.12.7 2006-05-05 * Merged libsepol test framework patch from Karl MacMillan. 1.12.6 2006-04-28 * Fixed cond_normalize to traverse the entire cond list at link time. 1.12.5 2006-04-03 * Merged fix for leak of optional package sections from Ivan Gyurdiev. 1.12.4 2006-03-29 * Generalize test for bitmap overflow in ebitmap_set_bit. 1.12.3 2006-03-27 * Fixed attr_convert_callback and expand_convert_type_set typemap bug. 1.12.2 2006-03-24 * Fixed avrule_block_write num_decls endian bug. 1.12.1 2006-03-20 * Fixed sepol_module_package_write buffer overflow bug. 1.12 2006-03-14 * Updated version for release. 1.11.20 2006-03-08 * Merged cond_evaluate_expr fix from Serge Hallyn (IBM). * Fixed bug in copy_avrule_list reported by Ivan Gyurdiev. 1.11.19 2006-02-21 * Merged sepol_policydb_mls_enabled interface and error handling changes from Ivan Gyurdiev. 1.11.18 2006-02-16 * Merged node_expand_addr bugfix and node_compare* change from Ivan Gyurdiev. 1.11.17 2006-02-15 * Merged nodes, ports: always prepend patch from Ivan Gyurdiev. * Merged bug fix patch from Ivan Gyurdiev. 1.11.16 2006-02-14 * Added a defined flag to level_datum_t for use by checkpolicy. 1.11.15 2006-02-14 * Merged nodecon support patch from Ivan Gyurdiev. * Merged cleanups patch from Ivan Gyurdiev. 1.11.14 2006-02-13 * Merged optionals in base patch from Joshua Brindle. 1.11.13 2006-02-07 * Merged seuser/user_extra support patch from Joshua Brindle. * Merged fix patch from Ivan Gyurdiev. 1.11.12 2006-02-02 * Merged clone record on set_con patch from Ivan Gyurdiev. 1.11.11 2006-02-01 * Merged assertion copying bugfix from Joshua Brindle. * Merged sepol_av_to_string patch from Joshua Brindle. 1.11.10 2006-01-30 * Merged cond_expr mapping and package section count bug fixes from Joshua Brindle. * Merged improve port/fcontext API patch from Ivan Gyurdiev. * Merged fixes for overflow bugs on 64-bit from Ivan Gyurdiev. 1.11.9 2006-01-12 * Merged size_t -> unsigned int patch from Ivan Gyurdiev. 1.11.8 2006-01-09 * Merged 2nd const in APIs patch from Ivan Gyurdiev. 1.11.7 2006-01-06 * Merged const in APIs patch from Ivan Gyurdiev. * Merged compare2 function patch from Ivan Gyurdiev. 1.11.6 2006-01-06 * Fixed hierarchy checker to only check allow rules. 1.11.5 2006-01-05 * Merged further fixes from Russell Coker, specifically: - av_to_string overflow checking - sepol_context_to_string error handling - hierarchy checking memory leak fixes and optimizations - avrule_block_read variable initialization * Marked deprecated code in genbools and genusers. 1.11.4 2006-01-05 * Merged bugfix for sepol_port_modify from Russell Coker. 1.11.3 2006-01-05 * Fixed bug in sepol_iface_modify error path noted by Ivan Gyurdiev. * Merged port ordering patch from Ivan Gyurdiev. 1.11.2 2006-01-04 * Merged patch series from Ivan Gyurdiev. This includes patches to: - support ordering of records in compare function - enable port interfaces - add interfaces for context validity and range checks - add include guards 1.11.1 2005-12-16 * Fixed mls_range_cpy bug. 1.10 2005-12-07 * Updated version for release. 1.9.42 2005-12-05 * Dropped handle from user_del_role interface. 1.9.41 2005-11-28 * Merged remove defrole from sepol patch from Ivan Gyurdiev. 1.9.40 2005-11-15 * Merged module function and map file cleanup from Ivan Gyurdiev. * Merged MLS and genusers cleanups from Ivan Gyurdiev. 1.9.39 2005-11-09 Prepare for removal of booleans* and *.users files. * Cleaned up sepol_genbools to not regenerate the image if there were no changes in the boolean values, including the degenerate case where there are no booleans or booleans.local files. * Cleaned up sepol_genusers to not warn on missing local.users. 1.9.38 2005-11-08 * Removed sepol_port_* from libsepol.map, as the port interfaces are not yet stable. 1.9.37 2005-11-04 * Merged context destroy cleanup patch from Ivan Gyurdiev. 1.9.36 2005-11-03 * Merged context_to_string interface change patch from Ivan Gyurdiev. 1.9.35 2005-11-01 * Added src/dso.h and src/*_internal.h. Added hidden_def for exported symbols used within libsepol. Added hidden for symbols that should not be exported by the wildcards in libsepol.map. 1.9.34 2005-10-31 * Merged record interface, record bugfix, and set_roles patches from Ivan Gyurdiev. 1.9.33 2005-10-27 * Merged count specification change from Ivan Gyurdiev. 1.9.32 2005-10-26 * Added further checking and error reporting to sepol_module_package_read and _info. 1.9.31 2005-10-26 * Merged sepol handle passing, DEBUG conversion, and memory leak fix patches from Ivan Gyurdiev. 1.9.30 2005-10-25 * Removed processing of system.users from sepol_genusers and dropped delusers logic. 1.9.29 2005-10-25 * Removed policydb_destroy from error path of policydb_read, since create/init/destroy/free of policydb is handled by the caller now. * Fixed sepol_module_package_read to handle a failed policydb_read properly. 1.9.28 2005-10-25 * Merged query/exists and count patches from Ivan Gyurdiev. 1.9.27 2005-10-25 * Merged fix for pruned types in expand code from Joshua Brindle. * Merged new module package format code from Joshua Brindle. 1.9.26 2005-10-24 * Merged context interface cleanup, record conversion code, key passing, and bug fix patches from Ivan Gyurdiev. 1.9.25 2005-10-21 * Merged users cleanup patch from Ivan Gyurdiev. 1.9.24 2005-10-21 * Merged user record memory leak fix from Ivan Gyurdiev. * Merged reorganize users patch from Ivan Gyurdiev. 1.9.23 2005-10-19 * Added check flag to expand_module() to control assertion and hierarchy checking on expansion. 1.9.22 2005-10-19 * Reworked check_assertions() and hierarchy_check_constraints() to take handles and use callback-based error reporting. * Changed expand_module() to call check_assertions() and hierarchy_check_constraints() prior to returning the expanded policy. 1.9.21 2005-10-18 * Changed sepol_module_package_set_file_contexts to copy the file contexts data since it is internally managed. 1.9.20 2005-10-18 * Added sepol_policy_file_set_handle interface to associate a handle with a policy file. * Added handle argument to policydb_from_image/to_image. * Added sepol_module_package_set_file_contexts interface. * Dropped sepol_module_package_create_file interface. * Reworked policydb_read/write, policydb_from_image/to_image, and sepol_module_package_read/write to use callback-based error reporting system rather than DEBUG. 1.9.19 2005-10-17 * Reworked link_packages, link_modules, and expand_module to use callback-based error reporting system rather than error buffering. 1.9.18 2005-10-14 * Merged conditional expression mapping fix in the module linking code from Joshua Brindle. 1.9.17 2005-10-13 * Hid sepol_module_package type definition, and added get interfaces. 1.9.16 2005-10-13 * Merged new callback-based error reporting system from Ivan Gyurdiev. 1.9.15 2005-10-13 * Merged support for require blocks inside conditionals from Joshua Brindle (Tresys). 1.9.14 2005-10-07 * Fixed use of policydb_from_image/to_image to ensure proper init of policydb. 1.9.13 2005-10-07 * Isolated policydb internal headers under . These headers should only be used by users of the static libsepol. Created new with new public types and interfaces for shared libsepol. Created new with public types and interfaces moved or wrapped from old module.h, link.h, and expand.h, adjusted for new public types for policydb and policy_file. Added public interfaces to libsepol.map. Some implementation changes visible to users of the static libsepol: 1) policydb_read no longer calls policydb_init. Caller must do so first. 2) policydb_init no longer takes policy_type argument. Caller must set policy_type separately. 3) expand_module automatically enables the global branch. Caller no longer needs to do so. 4) policydb_write uses the policy_type and policyvers from the policydb itself, and sepol_set_policyvers() has been removed. 1.9.12 2005-10-06 * Merged function renaming and static cleanup from Ivan Gyurdiev. 1.9.11 2005-10-05 * Merged bug fix for check_assertions handling of no assertions from Joshua Brindle (Tresys). 1.9.10 2005-10-04 * Merged iterate patch from Ivan Gyurdiev. 1.9.9 2005-10-03 * Merged MLS in modules patch from Joshua Brindle (Tresys). 1.9.8 2005-09-30 * Merged pointer typedef elimination patch from Ivan Gyurdiev. * Merged user list function, new mls functions, and bugfix patch from Ivan Gyurdiev. 1.9.7 2005-09-28 * Merged sepol_get_num_roles fix from Karl MacMillan (Tresys). 1.9.6 2005-09-23 * Merged bug fix patches from Joshua Brindle (Tresys). 1.9.5 2005-09-21 * Merged boolean record and memory leak fix patches from Ivan Gyurdiev. 1.9.4 2005-09-19 * Merged interface record patch from Ivan Gyurdiev. 1.9.3 2005-09-14 * Merged fix for sepol_enable/disable_debug from Ivan Gyurdiev. 1.9.2 2005-09-14 * Merged stddef.h patch and debug conversion patch from Ivan Gyurdiev. 1.9.1 2005-09-09 * Fixed expand_avtab and expand_cond_av_list to keep separate entries with identical keys but different enabled flags. 1.8 2005-09-06 * Updated version for release. 1.7.24 2005-08-31 * Fixed symtab_insert return value for duplicate declarations. 1.7.23 2005-08-31 * Merged fix for memory error in policy_module_destroy from Jason Tang (Tresys). 1.7.22 2005-08-26 * Merged fix for memory leak in sepol_context_to_sid from Jason Tang (Tresys). 1.7.21 2005-08-25 * Merged fixes for resource leaks on error paths and change to scope_destroy from Joshua Brindle (Tresys). 1.7.20 2005-08-23 * Merged more fixes for resource leaks on error paths from Serge Hallyn (IBM). Bugs found by Coverity. 1.7.19 2005-08-19 * Changed to treat all type conflicts as fatal errors. 1.7.18 2005-08-18 * Merged several error handling fixes from Serge Hallyn (IBM). Bugs found by Coverity. 1.7.17 2005-08-15 * Fixed further memory leaks found by valgrind. 1.7.16 2005-08-15 * Fixed several memory leaks found by valgrind. 1.7.15 2005-08-12 * Fixed empty list test in cond_write_av_list. Bug found by Coverity, reported by Serge Hallyn (IBM). * Merged patch to policydb_write to check errors when writing the type->attribute reverse map from Serge Hallyn (IBM). Bug found by Coverity. * Fixed policydb_destroy to properly handle NULL type_attr_map or attr_type_map. 1.7.14 2005-08-12 * Fixed use of uninitialized data by expand_avtab_node by clearing type_val_to_struct in policydb_index_others. 1.7.13 2005-08-11 * Improved memory use by SELinux by both reducing the avtab node size and reducing the number of avtab nodes (by not expanding attributes in TE rules when possible). Added expand_avtab and expand_cond_av_list functions for use by assertion checker, hierarchy checker, compatibility code, and dispol. Added new inline ebitmap operators and converted existing users of ebitmaps to the new operators for greater efficiency. Note: The binary policy format version has been incremented to version 20 as a result of these changes. 1.7.12 2005-08-10 * Fixed bug in constraint_node_clone handling of name sets. 1.7.11 2005-08-08 * Fix range_trans_clone to map the type values properly. 1.7.10 2005-08-02 * Merged patch to move module read/write code from libsemanage to libsepol from Jason Tang (Tresys). 1.7.9 2005-08-02 * Enabled further compiler warning flags and fixed them. 1.7.8 2005-08-02 * Merged user, context, port records patch from Ivan Gyurdiev. * Merged key extract function patch from Ivan Gyurdiev. 1.7.7 2005-07-27 * Merged mls_context_to_sid bugfix from Ivan Gyurdiev. 1.7.6 2005-07-26 * Merged context reorganization, memory leak fixes, port and interface loading, replacements for genusers and genbools, debug traceback, and bugfix patches from Ivan Gyurdiev. * Merged uninitialized variable bugfix from Dan Walsh. 1.7.5 2005-07-18 * Merged debug support, policydb conversion functions from Ivan Gyurdiev (Red Hat). * Removed genpolbools and genpolusers utilities. 1.7.4 2005-07-18 * Merged hierarchy check fix from Joshua Brindle (Tresys). 1.7.3 2005-07-13 * Merged header file cleanup and memory leak fix from Ivan Gyurdiev (Red Hat). 1.7.2 2005-07-11 * Merged genbools debugging message cleanup from Red Hat. 1.7.1 2005-07-06 * Merged loadable module support from Tresys Technology. 1.6 2005-06-20 * Updated version for release. 1.5.10 2005-05-19 * License changed to LGPL v2.1, see COPYING. 1.5.9 2005-05-16 * Added sepol_genbools_policydb and sepol_genusers_policydb for audit2why. 1.5.8 2005-05-13 * Added sepol_ prefix to Flask types to avoid namespace collision with libselinux. 1.5.7 2005-05-13 * Added sepol_compute_av_reason() for audit2why. 1.5.6 2005-04-25 * Fixed bug in role hierarchy checker. 1.5.5 2005-04-13 * Merged hierarchical type/role patch from Tresys Technology. * Merged MLS fixes from Darrel Goeddel of TCS. 1.5.4 2005-04-13 * Changed sepol_genusers to not delete users by default, and added a sepol_set_delusers function to enable deletion. Also, removed special case handling of system_u and user_u. 1.5.3 2005-03-29 * Merged booleans.local patch from Dan Walsh. 1.5.2 2005-03-16 * Added man page for sepol_check_context. 1.5.1 2005-03-15 * Added man page for sepol_genusers function. * Merged man pages for genpolusers and chkcon from Manoj Srivastava. 1.4 2005-03-09 * Updated version for release. 1.3.8 2005-03-08 * Cleaned up error handling in sepol_genusers and sepol_genbools. 1.3.7 2005-02-28 * Merged sepol_debug and fclose patch from Dan Walsh. 1.3.6 2005-02-22 * Changed sepol_genusers to also use getline and correctly handle EOL. 1.3.5 2005-02-17 * Merged range_transition support from Darrel Goeddel (TCS). 1.3.4 2005-02-16 * Added sepol_genusers function. 1.3.3 2005-02-14 * Merged endianness and compute_av patches from Darrel Goeddel (TCS). 1.3.2 2005-02-09 * Changed relabel Makefile target to use restorecon. 1.3.1 2005-01-26 * Merged enhanced MLS support from Darrel Goeddel (TCS). 1.2.1 2005-01-19 * Merged build fix patch from Manoj Srivastava. 1.2 2004-10-07 * MLS build fixes. * Added sepol_set_policydb_from_file and sepol_check_context for setfiles. 1.0 2004-08-19 * Initial public release. 0.4 2004-08-13 * Merged patch from Dan Walsh to ignore case on booleans. * Changed sepol_genbools* to preserve the original policy version. * Replaced exported global variables with set functions. * Moved genpolbools utility from checkpolicy to libsepol. * Added man pages for sepol_genbools* and genpolbools. 0.3 2004-08-10 * Added ChangeLog, COPYING, spec file. * Added sepol_genbools_array() for load_policy. * Created libsepol.map to limit exported symbols in shared library. 0.2 2004-08-09 * Exported other functions for checkpolicy and friends. * Renamed service and sidtab functions to avoid libselinux conflict. * Removed original code from checkpolicy, which now uses libsepol. * Code cleanup: kill legacy references to kernel types/functions. 0.1 2004-08-06 * Moved checkpolicy core logic into a library. * Exported sepol_genbools() for load_policy. libsepol-2.4/Makefile000066400000000000000000000006271246370572200146450ustar00rootroot00000000000000DISABLE_CIL ?= n export DISABLE_CIL all: $(MAKE) -C src $(MAKE) -C utils install: $(MAKE) -C include install $(MAKE) -C src install $(MAKE) -C utils install $(MAKE) -C man install relabel: $(MAKE) -C src relabel clean: $(MAKE) -C src clean $(MAKE) -C utils clean $(MAKE) -C tests clean indent: $(MAKE) -C src $@ $(MAKE) -C include $@ $(MAKE) -C utils $@ test: $(MAKE) -C tests test libsepol-2.4/VERSION000066400000000000000000000000041246370572200142420ustar00rootroot000000000000002.4 libsepol-2.4/cil/000077500000000000000000000000001246370572200137475ustar00rootroot00000000000000libsepol-2.4/cil/.gitignore000066400000000000000000000001451246370572200157370ustar00rootroot00000000000000*.swp *.gcda *.gcno *.o *.a src/cil_lexer.c unit_tests cov secilc docs/pdf/ docs/html/ docs/man8/ libsepol-2.4/cil/COPYING000066400000000000000000000033121246370572200150010ustar00rootroot00000000000000All files are licensed under the FreeBSD license, excepet for thid party components, which are subject to their respective licenses as specified in their source files. FreeBSD License 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. libsepol-2.4/cil/Makefile000066400000000000000000000047361246370572200154210ustar00rootroot00000000000000PREFIX ?= $(DESTDIR)/usr LIBDIR ?= $(PREFIX)/lib SHLIBDIR ?= $(DESTDIR)/lib INCLUDEDIR ?= $(PREFIX)/include SRCDIR ?= ./src TESTDIR ?= ./test UNITDIR ?= $(TESTDIR)/unit LIBCILDIR ?= $(SRCDIR) LEX = flex DEBUG = 0 SECILC = secilc UNIT = unit_tests SECILC_SRCS := secilc.c SECILC_OBJS := $(patsubst %.c,%.o,$(SECILC_SRCS)) TEST_SRCS := $(wildcard $(UNITDIR)/*.c) TEST_OBJS := $(patsubst %.c,%.o,$(TEST_SRCS)) LIBCIL_GENERATED := $(LIBCILDIR)/cil_lexer.c LIBCIL_SRCS := $(wildcard $(LIBCILDIR)/*.c) $(LIBCIL_GENERATED) LIBCIL_OBJS := $(patsubst %.c,%.o,$(LIBCIL_SRCS)) LIBCIL_INCLUDES := $(wildcard $(LIBCILDIR)/*.h) LIBCIL_STATIC := $(SRCDIR)/libcil.a LIBSEPOL_STATIC = /usr/lib/libsepol.a LIBS = LDFLAGS = COVCFLAGS = -fprofile-arcs -ftest-coverage -O0 CFLAGS ?= -Wall -Wshadow -Wextra -Wundef -Wmissing-format-attribute -Wcast-align -Wstrict-prototypes -Wpointer-arith -Wunused ifeq ($(DEBUG),1) override CFLAGS += -g3 -O0 -gdwarf-2 -fno-strict-aliasing -DDEBUG override LDFLAGS += -g else override CFLAGS += -O2 endif override CFLAGS += -I./include -I$(INCLUDEDIR) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 ARCH := $(patsubst i%86,i386,$(shell uname -m)) ifneq (,$(filter i386,$(ARCH))) TLSFLAGS += -mno-tls-direct-seg-refs endif ifneq (,$(filter x86_64,$(ARCH))) override LDFLAGS += -I/usr/lib64 override LIBSEPOL_STATIC = /usr/lib64/libsepol.a endif all: $(SECILC) %.o: %.c $(LIBCIL_INCLUDES) $(CC) $(CFLAGS) -c -o $@ $< $(LIBCIL_STATIC): $(LIBCIL_OBJS) $(AR) rcs $@ $^ ranlib $@ $(LIBCIL_GENERATED): $(LIBCILDIR)/cil_lexer.l $(LEX) -t $< > $@ $(UNIT): $(TEST_OBJS) $(LIBCIL_STATIC) $(CC) $(CFLAGS) -o $@ $^ $(LIBCIL_STATIC) $(LIBSEPOL_STATIC) $(LDFLAGS) $(SECILC): $(SECILC_OBJS) $(LIBCIL_STATIC) $(CC) $(CFLAGS) -o $@ $^ $(LIBCIL_STATIC) $(LIBSEPOL_STATIC) $(LDFLAGS) unit: $(SECILC) $(UNIT) # Requires lcov 1.9+ (--ignore-errors) coverage: CFLAGS += $(COVCFLAGS) coverage: clean unit ./unit_tests test -d cov || mkdir cov lcov --directory src --capture --output-file cov/app.info --ignore-errors source -b src lcov --remove cov/app.info '/usr/include/*' --remove cov/app.info 'sepol/*' --output-file cov/app.info genhtml -o ./cov/html ./cov/app.info test: $(SECILC) ./$(SECILC) test/policy.cil clean: rm -f $(SECILC) rm -f $(LIBCIL_STATIC) rm -f $(TEST_OBJS) $(SECILC_OBJS) rm -rf cov src/*.gcda src/*.gcno *.gcda *.gcno rm -f $(LIBCIL_OBJS) bare: clean rm -f $(LIBCIL_GENERATED) rm -f $(UNIT) rm -f policy.* rm -f file_contexts .PHONY: all bare clean coverage test unit libsepol-2.4/cil/README000066400000000000000000000034711246370572200146340ustar00rootroot00000000000000SELinux Common Intermediate Language (CIL) Compiler INTRODUCTION The SELinux CIL Compiler is a compiler that converts the CIL language as described on the CIL design wiki into a kernel binary policy file. Please see the CIL Design Wiki at: http://github.com/SELinuxProject/cil/wiki/ for more information about the goals and features on the CIL language. DEPENDENCIES gcc >= 4.5.1 libsepol-static >= 2.1.4 lcov >= 1.9 flex >= 2.5.35 BUILD STEPS Open a terminal client and execute the following command to download the source code: git clone https://github.com/SELinuxProject/cil.git Change directory into the "cil" directory. Run "make" with one of the following targets: make Build the CIL compiler (secilc) make unit Build the unit_test application to run unit tests make coverage Build the unit test binary and create coverage reports make clean Remove temporary build files make bare Remove temporary build files and compile binaries USAGE Execute 'secilc' with any number of CIL files as arguments. A binary policy and file_contexts file will be created. Use the '--help' option for more details. DOCUMENTATION There is a Docbook CIL Reference Guide in the docs directory, to build this in HTML and PDF format change to the docs directory and run: make html pdf There is also an secilc man page that can be built with: make man The documents will be located in the docs/html, docs/pdf and docs/man8 directories. To build the html and manpage the xmlto package is required. To build the pdf document the xmlto and dblatex packages are required. KNOWN ISSUES - Blocks inside of macros causes undefined behavior - Policy must be well formed. For example, invalid usage of sensitivities/categories/levels may create an unloaded binary - Recursive limits are not handled libsepol-2.4/cil/docs/000077500000000000000000000000001246370572200146775ustar00rootroot00000000000000libsepol-2.4/cil/docs/CIL_Reference_Guide.xml000066400000000000000000001075721246370572200211370ustar00rootroot00000000000000 ]>
Common Interface Language (CIL) Reference Guide 0.2 22nd May '14 Updated classmap/classmapping, added classmap to statements that utilise class_id's (defaultuser, typetransition etc.), update various examples to show anonymous classpermissionset's using expressions. CIL Information The statement definitions are those found in the source from: git clone dated 21st May '14. Not all possible alternate statement permutations are shown, however there should be enough variation to work out any other valid formats. There is also an example policy.cil file shown in the Appendix. The MLS components on contexts and user statements must be declared even if the policy does not support MCS/MLS. The CIL compiler will not build a policy unless it also has as a minimum: one allow rule, one sid, sidorder and sidcontext statement. The role object_r must be explicitly associated to contexts used for labeling objects. The original checkpolicy(8) and checkmodule(8) compilers did this by default - CIL does not. Be aware that CIL allows class statements to be declared in a namespace, however the policy author needs to note that applications (and the kernel) generally reference a class by its well known class identifier (e.g. zygote) however if declared in a namespace (e.g. (block zygote (class zygote (...))) or (block zygote (class class (...)))) it would be prefixed with that namespace (e.g. zygote.zygote or zygote.class). Unless the application / kernel code was updated the class would never be resolved, therefore it is recommended that classes are declared in the global namespace. Where possible use typeattribute's when defining source/target allow rules instead of multiple allow rules with individual type's. This will lead to the generation of much smaller kernel policy files. The site explains the language however some of the statement definitions are dated. Declarations Declarations may be named or anonymous and have three different forms: Named declarations - These create new objects that introduce a name or identifier, for example: (type process) - creates a type with an identifier of process. (typeattribute domain) - creates a typeattribute with an identifier of domain. (class file (read write)) - creates a class with an identifier of file that has read and write permissions associated to it. The list of declaration type statement keywords are: block optional common class classmap classmapping sid user role roleattribute type classpermission classpermissionset typeattribute typealias tunable sensitivity sensitivityalias category categoryalias categoryset level levelrange context ipaddr macro policycap Explicit anonymous declarations - These are currently restricted to IP addesses where they can be declared directly in statements by enclosing them within parentheses e.g. (127.0.0.1) or (::1). See the Network Labeling Statements section for examples. Anonymous declarations - These have been previously declared and the object already exists, therefore they may be referenced by their name or identifier within statements. For example the following declare all the components required to specify a context: now a portcon statement can be defined that uses these individual components to build a context as follows: Definitions Statements that build on the objects, for example: (typeattributeset domain (process)) - Adds the type 'process' to the typeattribute 'domain'. (allow domain process (file (read write)))) - Adds an allow rule referencing domain, process and the file class. Definitions may be repeated many times throughout the policy. Duplicates will resolve to a single definition during compilation. Symbol Character Set Symbols (any string not enclosed in double quotes) must only contain alphanumeric [a-z A-Z] [0-9] characters plus the following special characters: \.@=/-_$%@+!|&^: However symbols are checked for any specific character set limitations, for example: Names or identifiers must start with an alpa character [a-z A-Z], the remainder may be alphanumeric [a-z A-Z] [0-9] characters plus underscore [_] or hyphen [-]. IP addresses must conform to IPv4 or IPv6 format. Memory, ports, irqs must be numeric [0-9]. String Character Set Strings are enclosed within double quotes (e.g. "This is a string"), and may contain any character except the double quote ("). Comments Comments start with a semicolon ';' and end when a new line is started. Namespaces CIL supports namespaces via containers such as the block statement. When a block is resolved to form the parent / child relationship a dot '.' is used, for example the following allow rule: will resolve to the following kernel policy language statement: Global Namespace CIL has a global namespace that is always present. Any symbol that is declared outside a container is in the global namespace. To reference a symbol in global namespace, the symbol should be prefixed with a dot '.' as shown in the following example: Should the symbol not be prefixed with a dot, the current namespace would be searched first and then the global namespace (provided there is not a symbol of that name in the current namespace). Expressions Expressions may occur in the following CIL statements: booleanif tunableif classpermissionset typeattributeset roleattributeset categoryset constrain mlsconstrain validatetrans validatetrans CIL expressions use the prefix or Polish notation and may be nested (note that the kernel policy language uses postfix or reverse Polish notation). The syntax is as follows, where the parenthesis are part of the syntax: The number of expr_set's in an expr is dependent on the statement type (there are four different classes as defined below) that also influence the valid expr_key entries (e.g. dom, domby, incomp are only allowed in constraint statements). expr_key classpermissionset roleattributeset typeattributeset categoryset booleanif tunableif constrain mlsconstrain validatetrans mlsvalidatetrans dom X domby X incomp X eq X X ne X X and X X X X or X X X X not X X X X xor X X X all X X range X The classpermissionset, roleattributeset and typeattributeset statements allow expr_set to mix names and exprs with expr_key values of: and, or, xor, not, all as shown in the examples: This example includes all fs_type type entries except file.usermodehelper and file.proc_security in the associated typeattribute identifier all_fs_type_except_usermodehelper_and_proc_security: The cps_1 classpermissionset identifier includes all permissions except load_policy and setenforce: This example includes all permissions in the associated classpermissionset identifer security_all_perms: The categoryset statement allows expr_set to mix names and expr_key values of: and, or, not, xor, all, range as shown in the examples. Category expressions are also allowed in sensitivitycategory, level, and levelrange statements. The booleanif and tunableif statements only allow an expr_set to have one name or expr with expr_key values of and, or, xor, not, eq, neq as shown in the examples: The constrain, mlsconstrain, validatetrans and mlsvalidatetrans statements only allow an expr_set to have one name or expr with expr_key values of and, or, not, all, eq, neq, dom, domby, incomp. When expr_key is dom, domby or incomp, it must be followed by a string (e.g. h1, l2) and another string or a set of names. The following examples show CIL constraint statements and their policy language equivalents: Name String Used to define macro statement parameter string types: Alternatively: self The self keyword may be used as the target in AVC rule statements, and means that the target is the same as the source as shown in the following example:. &policy_config_statements; &container_statements; &call_macro_statements; &default_object_statements; &user_statements; &role_statements; &type_statements; &class_and_permission_statements; &access_vector_rules; &conditional_statements; &constraint_statements; &mls_labeling_statements; &context_statement; &sid_statements; &file_labeling_statements; &network_labeling_statements; &xen_statements; Example CIL Policy This is the example policy.cil file taken from the CIL compiler source code. &policy_cil;
libsepol-2.4/cil/docs/Makefile000066400000000000000000000024261246370572200163430ustar00rootroot00000000000000HTMLDIR ?= ./html PDFDIR ?= ./pdf MAN8DIR ?= ./man8 # The CIL Reference Guide first part CIL_REF_GUIDE = CIL_Reference_Guide.xml # All the docbook files that make up the guide: FILE_LIST ?= $(CIL_REF_GUIDE) $(wildcard cil*.xml) # xmlto generates a *.proc file that can be removed. PROC_FILE = CIL_Reference_Guide.proc # The secilc man page: MANPAGE = secilc.8.xml # look for xmlto and dblatex packages XMLTO = $(shell which xmlto 2> /dev/null | grep / | head -n1) DBLATEX = $(shell which dblatex 2> /dev/null | grep / | head -n1) # If no xmlto then exit as cannot proceed. ifeq ($(XMLTO),) $(error xmlto package not found - install package.) endif all: html pdf man html: $(FILE_LIST) $(XMLTO) html $(CIL_REF_GUIDE) @mkdir -p $(HTMLDIR) @for m in *.html; do if [ -f $$m ]; then mv $$m $(HTMLDIR); fi; done @rm -f $(PROC_FILE) pdf: $(FILE_LIST) # Check if dblatex is available ifeq ($(DBLATEX),) $(error dblatex package not found - install package for a pdf document.) endif $(XMLTO) --with-dblatex pdf $(CIL_REF_GUIDE) @mkdir -p $(PDFDIR) @for m in *.pdf; do if [ -f $$m ]; then mv $$m $(PDFDIR); fi; done @rm -f $(PROC_FILE) man: $(MANPAGE) $(XMLTO) man $(MANPAGE) @mkdir -p $(MAN8DIR) @for m in *.8; do if [ -f $$m ]; then mv $$m $(MAN8DIR); fi; done @rm -f $(MANPAGE).proc libsepol-2.4/cil/docs/cil_access_vector_rules.xml000066400000000000000000000347211246370572200223140ustar00rootroot00000000000000 Access Vector Rules allow Specifies the access allowed between a source and target type. Note that access may be refined by constraint rules based on the source, target and class (validatetrans or mlsvalidatetrans) or source, target class and permissions (constrain or mlsconstrain statements). Rule definition: Where: allow The allow keyword. source_id A single previously defined source type, typealias or typeattribute identifier. target_id A single previously defined target type, typealias or typeattribute identifier. The self keyword may be used instead to signify that source and target are the same. classpermissionset_id A single named or anonymous classpermissionset or a single set of classmap/classmapping identifiers. Examples: These examples show a selection of possible permutations of allow rules: auditallow Audit the access rights defined if there is a valid allow rule. Note: It does NOT allow access, it only audits the event. Rule definition: Where: auditallow The auditallow keyword. source_id A single previously defined source type, typealias or typeattribute identifier. target_id A single previously defined target type, typealias or typeattribute identifier. The self keyword may be used instead to signify that source and target are the same. classpermissionset_id A single named or anonymous classpermissionset or a single set of classmap/classmapping identifiers. Example: This example will log an audit event whenever the corresponding allow rule grants access to the specified permissions: dontaudit Do not audit the access rights defined when access denied. This stops excessive log entries for known events. Note that these rules can be omitted by the CIL compiler command line parameter -D or --disable-dontaudit flags. Rule definition: Where: dontaudit The dontaudit keyword. source_id A single previously defined source type, typealias or typeattribute identifier. target_id A single previously defined target type, typealias or typeattribute identifier. The self keyword may be used instead to signify that source and target are the same. classpermissionset_id A single named or anonymous classpermissionset or a single set of classmap/classmapping identifiers. Example: This example will not audit the denied access: neverallow Never allow access rights defined. This is a compiler enforced action that will stop compilation until the offending rules are modified. Note that these rules can be over-ridden by the CIL compiler command line parameter -N or --disable-neverallow flags. Rule definition: Where: neverallow The neverallow keyword. source_id A single previously defined source type, typealias or typeattribute identifier. target_id A single previously defined target type, typealias or typeattribute identifier. The self keyword may be used instead to signify that source and target are the same. classpermissionset_id A single named or anonymous classpermissionset or a single set of classmap/classmapping identifiers. Example: This example will not compile as type_3 is not allowed to be a source type for the allow rule: libsepol-2.4/cil/docs/cil_call_macro_statements.xml000066400000000000000000000217151246370572200226210ustar00rootroot00000000000000 Call / Macro Statements call Instantiate a macro within the current namespace. There may be zero or more parameters passed to the macro (with zero parameters this is similar to the blockinherit (call) / blockabstract (macro) statements). Each parameter passed contains an argument to be resolved by the macro, these can be named or anonymous but must conform to the parameter types defined in the macro statement. Statement definition: Where: call The call keyword. macro_id The identifier of the macro to be instantiated. param Zero or more parameters that are passed to the macro. Example: See the macro statement for an example. macro Declare a macro in the current namespace with its associated parameters. The macro identifier is used by the call statement to instantiate the macro and resolve any parameters. The call statement may be within the body of a macro. Note that when resolving macros the callers namespace is not checked, only the following places: Items defined inside the macro Items passed into the macro as arguments Items defined in the same namespace of the macro Items defined in the global namespace Statement definition: Where: macro The macro keyword. macro_id The macro identifier. param_type Zero or more parameters that are passed to the macro. The param_type is a keyword used to determine the declaration type (e.g. type, class, categoryset). The list of valid param_type entries are: type typealias role user sensitivity sensitivityalias category categoryalias categoryset (named or anonymous) level (named or anonymous) levelrange (named or anonymous) class classpermission (named or anonymous) ipaddr (named or anonymous) block name (a string) classmap param_id The parameter identifier used to reference the entry within the macro body (e.g. ARG1). cil_statement Zero or more valid CIL statements. Examples: This example will instantiate the binder_call macro in the calling namespace (my_domain) and replace ARG1 with appdomain and ARG2 with binderservicedomain: This example does not pass any parameters to the macro but adds a type identifier to the current namespace: This example passes an anonymous and named IP address to the macro: libsepol-2.4/cil/docs/cil_class_and_permission_statements.xml000066400000000000000000000624511246370572200247260ustar00rootroot00000000000000 Class and Permission Statements common Declares a common identifier in the current namespace with a set of common permissions that can be used by one or more class identifiers. The classcommon statement is used to associate a common identifier to a specific class identifier. Statement definition: Where: common The common keyword. common_id The common identifier. permission_id One or more permissions. Example: This common statement will associate the common identifier 'file' with the list of permissions: classcommon Associate a class identifier to a one or more permissions declared by a common identifier. Statement definition: Where: classcommon The classcommon keyword. class_id A single previously declared class identifier. common_id A single previously declared common identifier that defines the common permissions for that class. Example: This associates the dir class with the list of permissions declared by the file common identifier: class Declares a class and zero or more permissions in the current namespace. Statement definition: Where: class The class keyword. class_id The class identifier. permission_id Zero or more permissions declared for the class. Note that if zero permissions, an empty list is required as shown in the example. Examples: This example defines a set of permissions for the binder class indentifier: This example defines a common set of permissions to be used by the sem class, the (class sem ()) does not define any other permissions (i.e. an empty list): and will produce the following set of permissions for the sem class identifier of: This example, with the following combination of the common, classcommon and class statements: will produce a set of permissions for the dir class identifier of: classorder Defines the order of class's. This is a mandatory statement. Multiple classorder statements declared in the policy will form an ordered list. Statement definition: Where: classorder The classorder keyword. class_id One or more class identifiers. Example: This will produce an ordered list of "file dir process" classpermission Declares a class permission set identifier in the current namespace that can be used by one or more classpermissionsets to associate one or more classes and permissions to form a named set. Statement definition: Where: classpermission The classpermission keyword. classpermissionset_id The classpermissionset identifier. Example: See the classpermissionset statement for examples. classpermissionset Defines a class permission set identifier in the current namespace that associates a class and one or more permissions to form a named set. Nested expressions may be used to determine the required permissions as shown in the examples. Anonymous classpermissionsets may be used in av rules and constraints. Statement definition: Where: classpermissionset The classpermissionset keyword. classpermissionset_id The classpermissionset identifier. class_id A single previously declared class identifier. permission_id Zero or more permissions required by the class. Note that there must be at least one permission identifier or expr declared). expr Zero or more expr's, the valid operators and syntax are: (and (permission_id ...) (permission_id ...)) (or (permission_id ...) (permission_id ...)) (xor (permission_id ...) (permission_id ...)) (not (permission_id ...)) (all) Examples: These class permission set statements will resolve to the permission sets shown in the kernel policy language allow rules: classmap Declares a class map identifier in the current namespace and one or more class mapping identifiers. This will allow: Multiple classpermissionsets to be linked to a pair of classmap / classmapping identifiers. Multiple classs to be associated to statements and rules that support a list of classes: typetransition typechange typemember rangetransition roletransition defaultuser defaultrole defaulttype defaultrange validatetrans mlsvalidatetrans Statement definition: Where: classmap The classmap keyword. classmap_id The classmap identifier. classmapping_id One or more classmapping identifiers. Example: See the classmapping statement for examples. classmapping Define sets of classpermissionsets (named or anonymous) to form a consolidated classmapping set. Generally there are multiple classmapping statements with the same classmap and classmapping identifiers that form a set of different classpermissionset's. This is useful when multiple class / permissions are required in rules such as the allow rules (as shown in the examples). Statement definition: Where: classmapping The classmapping keyword. classmap_id A single previously declared classmap identifier. classmapping_id The classmapping identifier. classpermissionset_id A single named classpermissionset identifier or a single anonymous classpermissionset using expr's as required (see the classpermissionset statement). Examples: These class mapping statements will resolve to the permission sets shown in the kernel policy language allow rules: libsepol-2.4/cil/docs/cil_conditional_statements.xml000066400000000000000000000307041246370572200230260ustar00rootroot00000000000000 Conditional Statements boolean Declares a run time boolean as true or false in the current namespace. The booleanif statement contains the CIL code that will be in the binary policy file. Statement definition: Where: boolean The boolean keyword. boolean_id The boolean identifier. true | false The initial state of the boolean. This can be changed at run time using setsebool(8) and its status queried using getsebool(8). Example: See the booleanif statement for an example. booleanif Contains the run time conditional statements that are instantiated in the binary policy according to the computed boolean identifier(s) state. call statements are allowed within a booleanif, however the contents of the resulting macro must be limited to those of the booleanif statement (i.e. allow, auditallow, dontaudit, typemember, typetransition, typechange and the compile time tunableif statement)). Statement definition: Where: booleanif The booleanif keyword. boolean_id Either a single boolean identifier or one or more expr's. expr Zero or more expr's, the valid operators and syntax are: (and (boolean_id boolean_id)) (or (boolean_id boolean_id)) (xor (boolean_id boolean_id)) (eq (boolean_id boolean_id)) (neq (boolean_id boolean_id)) (not (boolean_id)) true An optional set of CIL statements that will be instantiated when the boolean is evaluated as true. false An optional set of CIL statements that will be instantiated when the boolean is evaluated as false. Examples: The second example also shows the kernel policy language equivalent: tunable Tunables are similar to booleans, however they are used to manage areas of CIL statements that may or may not be in the final CIL policy that will be compiled (whereas booleans are embedded in the binary policy and can be enabled or disabled during run-time). Note that tunables can be treated as booleans by the CIL compiler command line parameter -P or --preserve-tunables flags. Statement definition: Where: tunable The tunable keyword. tunable_id The tunable identifier. true | false The initial state of the tunable. Example: See the tunableif statement for an example. tunableif Compile time conditional statement that may or may not add CIL statements to be compiled. Statement definition: Where: tunableif The tunableif keyword. tunable_id Either a single tunable identifier or one or more expr's. expr Zero or more expr's, the valid operators and syntax are: (and (tunable_id tunable_id)) (or (tunable_id tunable_id)) (xor (tunable_id tunable_id)) (eq (tunable_id tunable_id)) (neq (tunable_id tunable_id)) (not (tunable_id)) true An optional set of CIL statements that will be instantiated when the tunable is evaluated as true. false An optional set of CIL statements that will be instantiated when the tunable is evaluated as false. Example: This example will not add the range transition rule to the binary policy: libsepol-2.4/cil/docs/cil_constraint_statements.xml000066400000000000000000000534611246370572200227140ustar00rootroot00000000000000 Constraint Statements constrain Enable constraints to be placed on the specified permissions of the object class based on the source and target security context components. Statement definition: Where: constrain The constrain keyword. classpermissionset_id A single named or anonymous classpermissionset or a single set of classmap/classmapping identifiers. expression There must be one constraint expression or one or more expr's. The expression consists of an operator and two operands as follows: (op u1 u2) (role_op r1 r2) (op t1 t2) (op u1 user_id) (op u2 user_id) (op r1 role_id) (op r2 role_id) (op t1 type_id) (op t2 type_id) where: u1, r1, t1 = Source context: user, role or type u2, r2, t2 = Target context: user, role or type and: op : eq neq role_op : eq neq dom domby incomp user_id : A single user identifier. role_id : A single role or roleattribute identifier. type_id : A single type, typealias or typeattribute identifier. expr Zero or more expr's, the valid operators and syntax are: (and expression expression) (or expression expression) (not expression) Examples: Two constrain statements are shown with their equivalent kernel policy language statements: validatetrans The validatetrans statement is only used for file related object classes where it is used to control the ability to change the objects security context based on old, new and the current process security context. Statement definition: Where: validatetrans The validatetrans keyword. class_id A single previously declared class or classmap identifier. expression There must be one constraint expression or one or more expr's. The expression consists of an operator and two operands as follows: (op u1 u2) (role_op r1 r2) (op t1 t2) (op u1 user_id) (op u2 user_id) (op u3 user_id) (op r1 role_id) (op r2 role_id) (op r3 role_id) (op t1 type_id) (op t2 type_id) (op t3 type_id) where: u1, r1, t1 = Old context: user, role or type u2, r2, t2 = New context: user, role or type u3, r3, t3 = Process context: user, role or type and: op : eq neq role_op : eq neq dom domby incomp user_id : A single user identifier. role_id : A single role or roleattribute identifier. type_id : A single type, typealias or typeattribute identifier. expr Zero or more expr's, the valid operators and syntax are: (and expression expression) (or expression expression) (not expression) Example: A validate transition statement with the equivalent kernel policy language statement: mlsconstrain Enable MLS constraints to be placed on the specified permissions of the object class based on the source and target security context components. Statement definition: Where: mlsconstrain The mlsconstrain keyword. classpermissionset_id A single named or anonymous classpermissionset or a single set of classmap/classmapping identifiers. expression There must be one constraint expression or one or more expr's. The expression consists of an operator and two operands as follows: (op u1 u2) (mls_role_op r1 r2) (op t1 t2) (mls_role_op l1 l2) (mls_role_op l1 h2) (mls_role_op h1 l2) (mls_role_op h1 h2) (mls_role_op l1 h1) (mls_role_op l2 h2) (op u1 user_id) (op u2 user_id) (op r1 role_id) (op r2 role_id) (op t1 type_id) (op t2 type_id) where: u1, r1, t1, l1, h1 = Source context: user, role, type, low level or high level u2, r2, t2, l2, h2 = Target context: user, role, type, low level or high level and: op : eq neq mls_role_op : eq neq dom domby incomp user_id : A single user identifier. role_id : A single role or roleattribute identifier. type_id : A single type, typealias or typeattribute identifier. expr Zero or more expr's, the valid operators and syntax are: (and expression expression) (or expression expression) (not expression) Example: An MLS constrain statement with the equivalent kernel policy language statement: mlsvalidatetrans The mlsvalidatetrans statement is only used for file related object classes where it is used to control the ability to change the objects security context based on old, new and the current process security context. Statement definition: Where: mlsvalidatetrans The mlsvalidatetrans keyword. class_id A single previously declared class or classmap identifier. expression There must be one constraint expression or one or more expr's. The expression consists of an operator and two operands as follows: (op u1 u2) (mls_role_op r1 r2) (op t1 t2) (mls_role_op l1 l2) (mls_role_op l1 h2) (mls_role_op h1 l2) (mls_role_op h1 h2) (mls_role_op l1 h1) (mls_role_op l2 h2) (op u1 user_id) (op u2 user_id) (op u3 user_id) (op r1 role_id) (op r2 role_id) (op r3 role_id) (op t1 type_id) (op t2 type_id) (op t3 type_id) where: u1, r1, t1, l1, h1 = Source context: user, role, type, low level or high level u2, r2, t2, l2, h2 = Target context: user, role, type, low level or high level u3, r3, t3 = Process context: user, role or type and: op : eq neq mls_role_op : eq neq dom domby incomp user_id : A single user identifier. role_id : A single role or roleattribute identifier. type_id : A single type, typealias or typeattribute identifier. expr Zero or more expr's, the valid operators and syntax are: (and expression expression) (or expression expression) (not expression) Example: An MLS validate transition statement with the equivalent kernel policy language statement: libsepol-2.4/cil/docs/cil_container_statements.xml000066400000000000000000000402251246370572200225040ustar00rootroot00000000000000 Container Statements block Start a new namespace where any CIL statement is valid. Statement definition: Where: block The block keyword. block_id The namespace identifier. cil_statement Zero or more valid CIL statements. Example: See the blockinherit statement for an example. blockabstract Declares the namespace as a 'template' and does not generate code until instantiated by another namespace that has a blockinherit statement. Statement definition: Where: block The block keyword. block_id The namespace identifier. blockabstract The blockabstract keyword. template_id The abstract namespace identifier. This must match the block_id entry. cil_statement Zero or more valid CIL statements forming the abstract block. Example: See the blockinherit statement for an example. blockinherit Used to add common policy rules to the current namespace via a template that has been defined with the blockabstract statement. Statement definition: Where: block The block keyword. block_id The namespace identifier. blockinherit The blockinherit keyword. template_id The inherited namespace identifier. cil_statement Zero or more valid CIL statements. Example: This example contains a template client_server that is instantiated in two blocks (netserver_app and netclient_app): optional Declare an optional namespace. All CIL statements in the optional block must be satisfied before instantiation in the binary policy. tunableif and macro statements are not allowed in optional containers. The same restrictions apply to CIL policy statements within optional's that apply to kernel policy statements, i.e. only the policy statements shown in the following table are valid: allow auditallow booleanif dontaudit typepermissive rangetransition role roleallow roleattribute roletransition type typealias typeattribute typechange typemember typetransition Statement definition: Where: optional The optional keyword. optional_id The optional namespace identifier. cil_statement Zero or more valid CIL statements. Example: This example will instantiate the optional block ext_gateway.move_file into policy providing all optional CIL statements can be resolved: in Allows the insertion of CIL statements into a named container (block, optional or macro). This statement is not allowed in booleanif or tunableif statements. Statement definition: Where: in The in keyword. container_id A valid block, optional or macro namespace identifier. cil_statement Zero or more valid CIL statements. Example: This will add rules to the container named system_server: libsepol-2.4/cil/docs/cil_context_statement.xml000066400000000000000000000130031246370572200220150ustar00rootroot00000000000000 Context Statement Contexts are formed using previously declared parameters and may be named or anonymous where: Named - The context is declared with a context identifer that is used as a reference. Anonymous - They are defined within the CIL labeling statement using user, role etc. identifiers. Each type is shown in the examples. context Declare an SELinux security context identifier for labeling. The range (or current and clearance levels) MUST be defined whether the policy is MLS/MCS enabled or not. Statement definition: Where: context The context keyword. context_id The context identifier. user_id A single previously declared user identifier. role_id A single previously declared role identifier. type_id A single previously declared type or typealias identifier. levelrange_id A single previously declared levelrange identifier. This entry may also be defined by anonymous or named level, sensitivity, sensitivityalias, category, categoryalias or categoryset as discussed in the Multi-Level Security Labeling Statements section and shown in the examples. Examples: This example uses a named context definition: to resolve/build a file_contexts entry of (assuming MLS enabled policy): This example uses an anonymous context where the previously declared user role type levelrange identifiers are used to specifiy two portcon statements: This example uses an anonymous context for the first and named context for the second in a netifcon statement: libsepol-2.4/cil/docs/cil_default_object_statements.xml000066400000000000000000000260221246370572200234730ustar00rootroot00000000000000 Default Object Statements These rules allow a default user, role, type and/or range to be used when computing a context for a new object. These require policy version 27 or 28 with kernels 3.5 or greater. defaultuser Allows the default user to be taken from the source or target context when computing a new context for the object class identifier. Requires policy version 27. Statement definition: Where: defaultuser The defaultuser keyword. class_id A single previously declared class or classmap identifier, or a list of previously declared class or classmap identifiers enclosed within parentheses. default A keyword of either source or target. Example: When creating new binder, property_service, zygote or memprotect objects the user component of the new security context will be taken from the source context: defaultrole Allows the default role to be taken from the source or target context when computing a new context for the object class identifier. Requires policy version 27. Where: defaultrole The defaultrole keyword. class_id A single previously declared class or classmap identifier, or a list of previously declared class or classmap identifiers enclosed within parentheses. default A keyword of either source or target. Example: When creating new binder, property_service or zygote objects the role component of the new security context will be taken from the target context: defaulttype Allows the default type to be taken from the source or target context when computing a new context for the object class identifier. Requires policy version 28. Statement definition: Where: defaulttype The defaulttype keyword. class_id A single previously declared class or classmap identifier, or a list of previously declared class or classmap identifiers enclosed within parentheses. default A keyword of either source or target. Example: When creating a new socket object, the type component of the new security context will be taken from the source context: defaultrange Allows the default level or range to be taken from the source or target context when computing a new context for the object class identifier. Requires policy version 27. Statement definition: Where: defaultrange The defaultrange keyword. class_id A single previously declared class or classmap identifier, or a list of previously declared class or classmap identifiers enclosed within parentheses. default A keyword of either source or target. range A keyword of either low, high or low-high. Example: When creating a new file object, the appropriate range component of the new security context will be taken from the target context: libsepol-2.4/cil/docs/cil_design.dia000066400000000000000000000152001246370572200174540ustar00rootroot00000000000000‹í]moãF’þî_A8À!h{úý%ÚÉ"»›Ã ÉáîÛ€–h[7´¨#åqüå~ûU5)¿HÔŒÆÍ–‡JÉÌØ¦ºØduÕSUOWÿíïܔه¢nÕòí9#ô<+–³j¾X^½=ÿÏßÿý¯öüïßým¾È¿…ÿ¯êü&ƒO,üîíùõz½úöÍ›»»;RÞ7ùºªI¹¸%Mñæÿò²ÌßÀEoο;˲§ÌóuŽ?ë~š¯×õââv]dËü¦x{~‘ÏÞ_ÕÕír~Þ^Õ]7«ÊªÎ>äåÛó¯.ý×ù›n˜7ÏÆùÈØ«üª¸¨‹üýþ¡)|9÷’¡WE½=ìͪjpÉú~µsÉžqðÏ'×tW5pÑò껯~*Öë¢þª½­î‡ãõÝì^A뛼¾Z,weÁó)Û‡Á‰¿4³JPnÄæ¹|¾¸‹ãŠ++®>®¸EónUÕë:_¬wE^TUYäËV꺾-^.§™å%¨ØÇ¦Å^>úåb½®>qÿ—yÙ2öÇ+îsWïU½˜|ñ>»bÏ(w‹ùúúÝ‘W;ú}¤Ñ?,šÅEYôÝýb¹løûa†ß~;Þ‚?~ßE\Ý.æEó 5{~Íž‘®»ËÞ|ê©o_wèƒi´å°½ˆ2¿/ênø<ºê¬{ÁÅyòª‹ÿ)fënz¿­óå<¯çÙ_³Tœ?"À‹ùÛóŸéódz=! ,ßÎóYUJDÄ„¡¶ç¼k1öq±=| È—We±Áʘ2Fœš0 ß¿L\Q7ïfU½ÜŃMÉËð¶cwZvƒ0úu±¸º^ïÞ+Ý“/k_&¬¹®îÞõàÃO;¾þEúæQ?PØß‹?ÖO4–uËB5V JDDDõ"(1ʨ©MByÚ™jÔÄ' òÖ5û^¨G°Ï®Û¼ÿüñ§=h÷#.bÞ¨–ë>Yøóì2¿Y”÷pKù²9Ïšõ=Ú2°JíGÿ£(?ëÅ,jr?ÿvJÏb¡ÄÒç_2Lèsí;L_"ç¹×üHxEi˜ À¤WË›¢ÿeËÛ›îA(¥×'~ÞŠøàoi{M<ÞŠ8Š%âá¾SgS  Q½' ‘ÄQ0F<ƒiå¬Ñ×e5{ŸåÉ$Å6I}ª˜ŒÒ’7JÖ¨‰&2ªMB`… iB5G‰fék.[ÕÕ¬hš¿$Ëß2íèc2L#4LrÃd¢neó‘›$†z‰zD†©¬®’Q:’Q2)„¹QR„p[I9‚›@àf9b%)P å| iVæM“].`&_Ãzÿ%™¦cDrÛ™LÓM“/ÙØÙ¥Öúì–5HIr)/ËênÉ!pzf©’©:в)é4[õÓbYôT‘M°­bÄAØÅMT[Ű.j&Šç´2ø‡䂿 þ2ɳj¹|W,ç~2Ÿ;Åž«àžàªƸðÚg«í{èã{|VÉy9—×uu·_Ë8ú]Y,¯>V1§D…ŠøDMþ` øÆA±`4;žjó›ì–LgÉוçYd¿}{.w)"[ƒ~æÂìgwØàu©ˆ…ØÃÅ\•¸ 1¾QS>ÜŽJîšÑ!äIÜ3ö…©’èçT}BT¬¾†0_hpqô1:sD[€Äl1úO?ü÷¿fÿ–߬¦g¿|ÿëo?üšpotÜÛ«– ùŽù²`%÷ ˆ(TQcYD3’ŒÄê†p̈)—ÈL3˜ÅvZ«Èðwï4{.•„+*—;É\‚§…ís(lwT¡ç³¬û,c{?G³`Ò).¶ Ò—c®o\7(dª"MÙ„Ibc‚éÀY‚¦9xIJÙ£wVÑ4ã[`€MÿP–‹UÓë­‚)‹‚{¢'<*¢1Ò †¤EI(ÇQÆåý‡Ïí î?‘Ç aÏ…¹£©Z0MP|XËŠš1Æ}Él*1ž©M\U žÛ—¨jj_€ËLÒ}À¾pËâª#T†’£r ’-·ÉÙšêØ è½óì¹5Çë§Òö¥Æ0!ð/ €à"2ß·ï+˜«Ã5î»QQ „­ Ù¹#VøDÏ8„?¯ŠeöK^Ë”ŒìQÆ”ü’€ºzËÄ=Ó8*þ1¢%4ÔåÓÏÈÖ‰ uÃç– n§gf€J2ovàþ©j†®8î(T‰)J¶¨mœ íb#Ý}ÓìÑNÐK«P=s/M÷$¤ûÅ"]‚tõ+!];@¶Yáb3q³Í^óHWO¡£¹ž“žðmt|»«‚ ߎßóp ææøÖù¬j‹os |<·?¾Ý×Oƒ gT'Òq•ÌË ]†ÇIøÆÂõáö†äù¢{¾]%Lžo„Ô.NúÀ‹”õª¸±¶5 bXo‘ÀiD^Ñ)]½Óë÷ÜßR*%\€­Cl9ÀÞiy8†çqŸá‘kÆn“> ái1öå|öé ÁsK9ÛNφ ÁýõÔR°¸L•֓aœÕÞ•X­Dü¤mÿ<ûÕ“ïx¬Ò‰ |j>ÅøÎ_'iËå…¡Íåq½ ÃZµ¼J…•ÔxÈ «DN8FÛ£Š)„gò–Ó¦„öm¢ópA àáZÒ§"ópƒç–€n§gzÿ§ý;§‘ã)Ý2[AËàí[*‘';WÒ;¹~}þŽhJ•œ8A~¬U¯—*‚v„éF㯘'qÄ©i·{ˆ±—béƒ7q„L+yŽN¿ì›Ò$Å|€cÌÄu†iEeE ꙡŽá‰4BrÿFï,{¯äŒ¼/¦­LŽä´ Ù¾ÖüÙ‡ù±ò#n€UnýéO6îÆSÛ1ÕfH˜öŽ„"G‚ Sv$zv¤GSzdŒgeÐr#b"ãfEî|÷ÖÈÒˆHùÚd‘>ª†É3Y+‚)GBùÐ76ÓÅ<2mµƒ£3mÃçö§ ¹?¢já‹<Çèšf7ZÞï::©ÃTL?}çLéÓËêˆpâ‹Á¬ŠÆ"°ÜƵfÎ8uÃ¥˜‚dI­lÛÚ»èÄ—}óìõó€ñÆ´f&íV<µÄŽ Hìö:Ä!À,lâHäŽ"Ú¤Ž&Ú—èH²:þÔDE¢vÔ0…Q#ܶ!† ¼8ÛŠá›mwRuŒmýÓë‡ÂÔßRÚ¶qjHã#`á¤ñJ[¡Y­çD X[¢KÙrÚb > ¬‘ŽZ3v•0‘ækƒ©Q’Ýn´Šh’PˆÏiM%Gb7î‹™D TbFuêÎŒrD;ç1œV,j¡$I«ýæ1*ìÔë€ó{Ç¢7¶Ý7É~ͤ”ùc,-qr°6„%Ì+ÁZ7„Á§Tl¢aõª•’PÇd""$lû MLØvœØVÒÌ7ÊÓ£ãž"½/Ï ‘ ;1¤mF>1dˆ&N£ÊÓ_$ž¨Ð¾Wåx§c^Ð# ÞªœŠ¬rÌ0ÅW¾s`ÀÔpËÛ=±¸6N9jýÖC59å¤öz@¥Žbígï¥Ôu›O ÆJ!Ö‰…X& Ä’4rˆµo¡‹º1BxÖ¿ 1OAIœI¿°µe˜²³²Ý„" ñzÿ<{=‘1ÚùKµ3i¡ŸÖBÿÈZ=`¡¿IÊ2¦ 'BÅÍ–*¿¤­Ï§À “AªEJGKÉ”è…Â>ULé”n4“*<°EEqCZ4H®KðréUώ­êjV¤SŽßÝQÃdFšÞ &SIûrV|£î9Ê´r8˜&KJµÄÅÝ 4ÀôRž­Ó53@^×óVåLÄMëR¤p|¸È+óûΤxióÝÃïþYöê¦_wÙz§Û“Ðû•N-“Ád%©ÚšŠ‰{oÄè.øFŠnkç!ÁÝ42AÞ‘B^7€…’]ñ•»¸&JlªËAˆëŠËÒE…¼áÓKl†uSáûH/‰bÙ çÞ%>h"YÌ0EY¾…³g ¡†ûØZp×¾9¥|M­)X8C˜°Õ@É—¶z8<ÌÚ3ÍÞ8 n§UOËEгN¬Ärx•t¯ÃeP|€Äóé},ÜS7ug æŒ)hÜ‚æÞ ÏePRÆ^çûæÙò¤%«d"-ÚB9QHÑ×I¨(1@¸bq·SôÊáFΦ|îœr=žúaâ3)›Ò§Ž)2BFƒ’·ú(Æi#gcœ‘®•;ãTVWÉ6E·MýÚ˜lÓmS0ÛŠKÌCè 6zyp÷ƒ–‰¢„ÑAø( Ó/yÝÙïu‘°StûÔ¯‘É<°AÒtÆåLØ “Ä8§ãö¨ÓÎ/I:ß×P*&Ì IÅÆïŒÛ?ÏþKñ®R«º“;6/öV’Tô­ÒðSﱨ’*êFA°½HÁ]$JMxÜ#ïçtH­N£‰yòõR3sP­OSyúe_hM›kX'ùìýU]Ý.çÛ/ªª,òe+s]ßÇÂv€Ǫ̈^xªbÜîÌ­IÛž‰‚‚"ã¡zc€Á³EùîâvQ‚µlÖ ¡Mó®J& ü%á=6˜Ž…;ã&LÇ=0„€Œ)·àù¸"q»{„ÎèÿÊõ–Ïsý«#LŽß¿î‰ä4#:•Ý…ª+¥C9Ìáñȯõ–S½ÝxÏ{߃i/É…ojk/ƒ8ÞÁå:˜Ç$î³Aƒ÷+”Ã[9\MÑþ·A]äî˜^âû>ª[01 ¬çÛ²¸êÆP€—ƒêÆqc¥·"«[øôþtê¶'²×ÁÜ Gô„Y\ÿ­BE«f ß>nÜåcë˼i²ËE™ª[Ñcú>eL!ýk[Z¹Œð¥mDLn2Ú#c—D…›‚`Ky©h9(Ú7Ëž+9QÌP‚ëDL>±èH‡œÃ¤cŸÃô¬L±±êL8‹¼³Í;/!õ„óØÛÚÂ'—€n§hÁd M$Æ6.ªšuB$]G$ouNŒ變ú&ƒ=O876ÎíÓÅ„sLjs͹I…O»0õd&G”R{Iœ±©ßÕ-,(ûÒmþ‡Ý}Óì ­ÓJà}IúÒ:Q‚º_,Ô 9›I«×Ùƒ§Ã›a{!ÜXs‰?Dªv‹QØVéMcàÐBúˆ¾Ç¥Gúg/#íH´‰®#ã–6y[k¢nÊ^ÓRû"6ç–âïVÏL0Å…i$P9laSÍ:)ÂbžÇ‚ÛóZÆÇ€_”Õì}–NÞŽî{U1yÀÆß&œÚÉ­c2R鸅&nµg·qf}¡É0Ë<ý޹èø¾yözM­[·i˜“)Oøcî^­ÖdÂyUÂÓë0#„,,uu»´­6E>r€é¥Š®‰Â*+h‹>™ˆ¬mÏdD?"D¿â”òy]Å©ŒÏ`èŸgï¥R;攲´A÷ÔüJHs5Ã_'±k‰JØÓpÂÅËϘ>l•·b8±>²•„ú Š v±-Ž–¥ã™ŽàöêdŠpÇ™ã5j€Üë¨(2nòu|'o‘ÓØÂÞ¸9Þà¹%ÐÛéY0Çʇ:RâËpTF.'8#=–”ŒŠ©×+=§ÑèÉ”}óìWO®´¿”ÑÄf81ÐkB’)æ•Ø Æ °ÐÕ1@o+fz qžQ9*ЛÚvðöêc¼#¼Ál+æ6|w­{’rÂ_´ƒ¼‘wІO/ÞN× 4èHÿ6y() âtJÉÀ‚Xª=ä}±>òî™e¿rrÕ^)y¼'xU൯xm8{ ûÒpŠ´µ˜+¼“ÂîrK´ØlZÜÍ˲ºËλ,ïyvÐþÄ­óðî,:OH8:îSÔ„Ç×ϲðX+wÇ£ð2°¯‡A¢ö Òa}g·Ú⩨}gÕ 5šµÁ@™j"hÜ>³!¾Í,cÄZp³‚¨Ïl]4x±Ôiö.µO'“G![ØÐ-Ë`óW·YcÔµMf5¾[­—Õ/=“òà8¿g†½}šg­'¦©¨u*1þ&L·¯sÔ‚ æbqÑ&`5‰Z|F1Ü‹÷Øb X˜¨ý ƒ'öÅu„Æ3¾é³–ÐcÂû‹V pèX}C¨Ž|èê2ˆaj*4v7·„ë¨õ‹à™¥v³z~Œh;á`Çâ*ÃÌHa¾õ¸ô˜ÚDV´à©¥ Àš…ŸƒDýflìðWÏäHlö&ð¨6Éî®1‰¿c³³Uµj2ì­œ=Æ©ðÛda·D²£´áçK‚“DÆ=Çd —›«©&Ñ!€D3Þ4û>›-ÊMŽ-Y¦è–iW“e£ebtž›0CxdÑD;*§Êcž~³–éq”:ðÀ.Ðð¸®ìòvÙ–»îòòý6dkË-Hó€ >A2ärQDZr¶Xú HV.à'ꮋÙûbîK#ï‹û»ªžC`‹#Á§Ïº „Æí¸XŽX®óÅîÏ‹˜çëcÞÛÙú¶l8«jøkU-çþŠøuã¤\–÷Ù¼˜•yûÊ›º-ÝÍñÖÖ×pKͺX‘ì_þ2,«´…i>Ÿã ð£u~ñXÏi§vY檺½y«¬f¹/ñ\•Õü Ÿz³ÊgÅæãäì·®bƒãlÄølʪ‹Ëë À×Xwyzß9kJµZóÇJ <²VüÝ¢,³ õ6ÏJxx5ÉζªWÍuu[ÎñJxÎ뺺÷o+GíÞ<ä™b{¦>s”\Ó(]S0AÜúº@£¶ÞõB4Q˜RÄãeÊQd¾ÿí÷d’¢wÜíQÃd’Fi’ø‡ÓùãÜ RÅ=N´gÅYŠÇȃ<ÞÊ5r ý¯À•,Ô1,T¿VJ#%H6ú-¸,n²ÑoæT¾Íý9ÜLïFxüvÆûÐìFŽ‹æËû.mÃÑ»¼ñÔ¿‡p²•7ý*o0f_¯‹›V¹«lUÔ0Î Vj¢Þ²ªÞß®ÃË3?ôÎï!mÌ:ÿüñ§ì¿ï$û¾ino0*Í!´m¯mÚªys;Ã=—·åäa* <†l¹hؘìðÒªÛ /ÙàQÚ`9y¼=•.êææ)«š®¥ö{ìG‘Xý±5nõ°8yNß¾+êâ Mîª.>,ªÛ¦¼¼ü:ÿPdE±<«‹U ¶~ëëÌ¿x§›¼çV6´U’uÒgySdÕ¥Oâ¶»ãêÛ²hM(žk³hšMŠôìb±¾ÉW+t‘#…¼òC,üš¼-š°Él&“{øî:KF÷Unû}™ßõwgí7ðÿUß|wöÿÙ;C!5»libsepol-2.4/cil/docs/cil_design.jpeg000066400000000000000000004247211246370572200176600ustar00rootroot00000000000000ÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀÖÈ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?÷ú(¢€ (¢€ (¢€ (¢€9MkÄqÍ«¦·%•¸»š+{8íâd)­ï )rÌPŸ•—µVƒÄ£ýƒuÖ|ßÜØ?îטÏÚ;l^zñ×­lÂ+W³MgªêvVóÌgšÒÞD;“–<¡uÜy;YrI=ê;ŸZÍhÁ¨_ZI¥&¥ð˜Ë¬¯¿#çF]¿¼nÏNh£¢«ØÛKig^Ï{"ç3Üù$ó±UxéÀ=y«QEQEQEQEQEQEQEQEZßPµº»»µ†]ÓYºÇ:í#c2‡$`ü¬µf¸¨5¥x«ÄÑKk©,——µ¬Ñé³Í£Æ¹ÞˆTÀƒ“Æ+›ðîŽÖ°yš­œï4zt±j–°ès«Þ±Q¸<ÅÙ'mÀ௩ÆÐH Y¢¼¦=Ä1x_S´¼‚æ]a¥´yçeiÄöA—÷*WfòŠ2 ÇþZ šÏërÚd_fi´ÇÖ„Ïhš<Ö0@¢Òe?º’›nz)'î9õ ȃÄúMÖ¦Ú|O$Ë+B]-e0‡\î_7nÍû9©tø,­µ Øílæ•bV%Yb` #åÀ {×' ¸ÓüEooáñ®$Rß»^ØÝY0´Dff’D•`–%€W “÷};êÅ´ñ=•Ö‰ý²ðÜÛéß`[ó<¨0#!˜Œ)$²…Éw&¸}Ú9µ lt»•ÕWÄ—’IövÙöqq.ðeÆÝ¤evg;¹ÇzŽÇ@¿¸ðýŒºdÆY|ml‘Í ~Ñòr>ø%N:ŒŠõU`êNAÕýµœ¶‘\I±îæò!IÞûñÇO•äñÅy¬Ö:|z®Ÿ}£h#icuáù£H±!,ñJUVù‰%‡Í´}k¦ñÆkxt+›Ý/ûBÖÓPßp‚ÐܰŒÃ*ýÀ¬HÞcÈôµoéšœ:­´³À²*Çq5±;¢‘£cÁÕ7[ü¿/a\)nÛ‘šô‡’ò(²ÈŽÆebm+ÃsœÜ`ºzq™«‡ñõ…åãKö[IçχõXG•oÞ:ñxþ&ÁÀêpqXž,Ñ¢Ò¡»ŽÓM•,&‡MóR*&”^ <ñ™ ž¤äñ“@§Uî¯í¬å´ŠâMw7‘ÚN÷ØÏŽ:|¨Ç'Ž+€’ÂGÓµ‰´­*êßJ]CO¹‚Óì 7“4o;¤$U`n*prjêV0êºüÚ­îƒus§G¬C!é¯#ÈÎ#O³N2Ã(ÉQÏrs6¾›[Ã¥7Û%ñçŸ#@K5³Ë8Ãdªe*p~S{æ€;ë ûmSO·¿³“Ͷ¹e‰ö•ܤdÇ­X¯,Ót‹koønÖmàZYÌ‹­Ú&šàÌâPìs:‡ÚIPÀðyÅuþ²xü9-½Í¬‘YËq9¶µ¹NRÙœìFSÐm<)èc¹amªiö÷öry¶×1¬±>Ò»”Œƒƒ‚8õ¨£Ôá“Z¸Ò‚ÉçÁoË1iYEç9³Çq^a£èú}¦› Ã©øfêK [‚öÙ4©ý;# OÞeC ȸÎiñhÚò]YK©ÙÞ]XC¤Y&¥ji' %ÁÙ¸gÌ)¹ ÆXÿu€=fŠòýGG½¸ñmì·¡–K¸$Ó®×FžâH¡U “+…„nX ä“j;€Ö«o¨Ç¦ÜG¨7ˆoYãˆùßgy'ïŒì ©Ã’Sšôz˽×ì,¬5‹²Ï(Òžî8Óæ]± p3€IF®9ëÖ¹ŸYÿg\ÝÚA§*Ú¤ÿÄÁô¹,f™Áa¶PüÊÀr\qɪ:®oñ"Ñê7ö“=¤ñX3y¨Öˆ¥VP¸Üd òg$óƒšôu`è¬:š‚êþÚÎ[H®$Ø÷sy¤ï}Œøã§ÊŒrxâ¸OFþƺ¾MЖk+«Qq[<±<‚rGEæW w>ff²môQäFu- Üiv^ óRÑäT[w³Á1ÛìÍ`Hç'¹E6=¾Zl]©´mÆÓµ:€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +Ÿÿ„ïÁÿô5èø1‡ÿŠ£þ¿ÿÐסÿàÆþ*€: +ÇÅžÔï#³°ñ•wu&vCìr;`p äà Ø Šó?ÛßO⿵[hëÕ¾§f#¹‹L–I¥ƒ|[ßí!‚*m.¥0xœg!×¹Õ§³ÓÊj7ÅÃÎÍnZYm~ÚÌÊU™v†8å¨Ò¨®SÀö"ÎÞý¢m–ÒÌ­ºiRØGÚlŽF$€N03ŸS\æ£ß'ŠÒ[âÐêI¨Í+Ü&3<ð–}ªn·ù~^¸RÜ·#4ßÙjÐ^Ì-¶Kà¶ŽæKi“9`»ˆÊç(ÞŸJv‘©Ã­hÖZ¥²È°]À“Ʋ+FpHÏ>µÀx7F‡OÕt[KD‘nŸB³†)ÞÁ˜Å:y»Ã8Så¶ÖA–#8ÇlU o ê6Ñ?±,'³Ö.4Ẕ!I ¦$(²1Æ0!w· Åz•¶Ÿ Åk–4“°ÜN^G.çŸVb*Åy2h >•y­¼©Óié5•¾‰qb¿-ÜlÒîÛ˜.í̽†I8èZºiž¾‡KÒ¡•b¶“ʱ‰B$„‚v€¾¤žž´¯Eyz5ܱk6P鬚uÄšK¬všTÖ1gÎ+A³ p#¹î¼;§ /Y×­íìþ˧™â’Þ4dY1(rƒ§QÎ;ç½tTW›iÚlɯX‘¥Ýǯ&«q-ö¢Ð0I-I“hó±µÔ©Œ*J8Í`hº}å߃4…ðÆweªbÊ.®Œ-›tCËS!-´® Øðô hª÷¶6Ú¸·»ÌˆI¡wó#‡SÇ£(?…y­¾ ðÇŠ…„'Ÿ£K±ƒCžÉ^]‚ŽÞd‡8%sž2OÔèÚ:i,™l¬µ”ºlFBˆBI2»Œ±è_’yQ€@[ûgÔ¥ÓÖLÝE Nñí<#–U9éÉFã¯J‹HÔáÖ´k-RÙdX.àIãY €#8$gŸZàü%¤¥ž¿§]jš<ÆêM*Þ.e±ghåæ ºM§Ë; c,FFN+6ÛÂú‡…4OìK ìõ‹xn¥RC)‰ ,Œq† ]Ämè1@·PÏ;C$ –Q,› F#IÜÙ#Ž1ÆNHã¸ó­Fû7[HÍյŀ‚[{ {2¯ÏÎÙ¼É0H%sž2OšmÆÝ284Qmio¬—Yi’Yy¨læC |ÈC»ãé”WœxVh¼1 æÝ%ÞÎ8í㉥=•ÅÄ­'–E“kå.0>c^@Q@Q@gêzî¢y_ÚÚ­‡Ÿ/íw üc8ÜFq‘ÓÔV…y¿Žì,õ?Š_lïí »µ“ûK|3Æ$FÄ FTðp@?…uðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅQÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMðø?þ†½ÿ0ÿñTÂwàÿúô?üÃÿÅTsø/Á6¶òÜ\xkÃðÁ’I,!UE$’WÎk‡Ÿ\ørצðòOA˜ä»Ò<=Ð,€ò›Èœ`ädÀ‚s@çü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñUçÿÛž÷—Ÿõ[+Uæk« D#…Þw#$('ð:Wa£hüC§%þ‘¡øröÕ°7Ãc ÚHk ¹VÁS‚3È  øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€øNüÿC^‡ÿƒøª?á;ðý zþ aÿâ¨ÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&€44ÍwGÖüßìVÆÿÉÇ™öK„—fsŒí'ÁëèkB¼ßÀ–zgÅ/ˆVvZZÇý›²#¢æ' 8$ŸÆ½"€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<Ÿá„ü7©ü-ѯ/ü?¥]ÝIçïš{(ävÄò–#'øWqÿ'ƒÿèTÐÿð]ÿ\ÿÁ/ù$:ý¼éD•ß’K1’OjÀÿ„Áÿô*hø.‡ÿ‰£þOÿЩ¡ÿàºþ&´tmgOñ—¥¥Ü‹‹9K)\àx È=E_ þOÿЩ¡ÿàºþ&øA<ÿB¦‡ÿ‚èøš»c­E{~lM­Í½ÊÚEvñΪ ,ŒêàŸ˜Û=ºrkN€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ¢€9ÿøA<ÿB¦‡ÿ‚èøš?áðý šþ ¡ÿâk ª÷WöÖrÚEq&Ç»›È„m'{ìgÇ>Tc“Çÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMtP?ÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMtP?ÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMtP?ÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMtP?ÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMtP?ÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMtP?ÿ'ƒÿèTÐÿð]ÿGü žÿ¡SCÿÁt?üMtP—ëZ¢|^øý“¥XØyßÚ>gÙ-Ò-ø·ÎÐ3Œž¾¦½B¼ÿÅ¿òW¾ÜOÿIÖ½€ ¥¤jpëZ=ž§l²$p¬Ñ¬€ Ã#8$gñ®bÚÎÒ?êë:MÅÍü—húuïØÞdŽ- E†Jç9ç5‰m¦´O /ˆ4kËÍ2 Å- ³yÌW8ix€';C€Ä|§=3šôú+ÊcÓ/m$Ðînôéu^;kXšÚ÷M’àF“¹.G˨o˜’rP}jÆ£ß'ŠÒ[âÐêI¨Í+Ü&3<ð–}ªn·ù~^¸RÜ·#4éÔWãÓÛÆ~:ž-ý ²¾-vÍqšßÆ –ºlŽOYÓõ‡ðב&ˆßÚÚY{ ßN–îä6é F’£ ¢ˆù$’OCŒd¢¸ ½îäøÚúÒ̦³1 §Üºmaþ‡“mÉܹr0Ob¦€ÓéwqÚ[ÊM6ž“Y[è—+òÝÆÍ!Þí¹‚îÜËØd“@£umg-¤Wl{¹¼ˆFÒw¾Æ|qÓåF9Õ|;io­7@ót[]^)üˆôó2kGG)©Èó<¼…‘“Ó5>¥áá5ω5H´¹MòjvrXJ!mê‹°c‡ Ž»H=1@Ta··ÐôD·±´•­ì­öÃmÜåQxEÜy<`dýMyþ£ß'ŠÒ[âÐêI¨Í+Ü&3<ð–}ªn·ù~^¸RÜ·#5ZëL–$ñ5¾Ÿ¤Ëv÷z~¡¾î]&Xn•رùÇ‹€IÂ…hÕ”åAÁjZóØ,¾ËãÈ®`ÓZòiæ_:[­.E{Uí-Ñù6p?w×,k£»ºƒÄ~žáý½½õ£m1GºpŒ ª¹ÎG ä×·±¶µ¸»¸†=²ÝÈ%·½‚*ÏO•qéV+άtÛ‰¼«Eg¥[YÉgp—vç=€¸–0® …þeåvЂj¶“¡ÃâkK×5M1®-uX/®Ý'r*1¶[t~Ùò0ø·ÈÍzuRÒ58u­ËT¶Y ¸xÖ@`Î çÖ¸¯ èsi³xZïì7]M§M£4ˆÛÙ±A+I»ºrszf‹~<-¦ÛèZ>¡§kQèóG¨K$JL@"yŒfÝ‚¸'`|½(Öu]N"È]Ü,š(qî’Ez‘Æ\gÛ5v¼¾M1dû[xE¼±ÒËé»­ÚÍáß2]«;ˆØò§Þ|`ã©ÆkÐí5(¯/ïí#ŽPÖN‘É#±™>çœ\ôê(íæÚv›2kÖ$iwqëɪÜK}¨´ KRdÚ<ìmu*c €’¤3]ÃýÁzJý€ZÞIeڷǶVp½<ädŒ(§¢¼©lâ·×4oµiwI­~V¹¾hVXÏœcýé]v”‚vã ÅEöMfohZ]†Ÿ¨Ã¨éÚ Í¤²4¤Â8*ÈÀIVÚÀã¡Ízõí¾as}w'—mmM+ਠ’p9<Ò¦V¡”ä‘^g&‰þ—â‹}CžÏL¹Ñ¼”µžÑ ÝâLÀù†PÇ'œf¨jZ•mo¥´vñÆ»Ws–8÷$’O¹5JËAÓ4ñ§‹[o,iöÍikó±òâm™^O?êÓ““ǹ cÃ~2ÔõY-n.¬œÙ]Ú5×î´ëˆ¾Ë€TË Ù.A<®ÞGƒš±ájž ž nmÂÚ]Y›¥O¸‡È9M¨el—!ÉÊãîœksNðæ™¤ÜyÖQÏV/µJÐÆP‘–(Ÿð)tÏiº<í-ŒsÄ •}ªV‰ á#,Q9ÂjQEQEQEQEQEQEæúÅ»ü@ø{á{©vøkCŠ5+L²=ôò«4cr0>Z­Ûæ†à¯¢A6¶ñ[ÛÅ0D#Ž5 ¨ `Æ+ÏôÙ—ÃÿõÛ[ñ"Ÿ[ÛO§H±±F6ñ2É60›Œc$ôJ+Ìük`¾½>>ÐÄv°}¡?·íX‹èÑ7ªî %RIåÉv$õ é•ç&]CÃxBÜHú·ˆn#‚Í6eQˆòHäµFIäóœ`=Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ?ð—ü•÷ ÿÒv¯@¯?ð—ü•÷ ÿÒv«´-"ÿH†öóK²¸»[ÛòÀ®â3w)¸Œí!˜Óæ>´Ø‹ˆZåí„Ñ™ÑFˆ0ܪIˆê*ÀcéRWœjZtš>¿®Â=Hï›&¡¨%½Ã(GÀh%bŠXÊ \uïíÛ×ÓZÈßßËx5Ylmç°†ÜÍrKŸõƒÊR œ”8œPsEyæ‹­ëzôÚ³jrÚy©© §Ž(L’›{ˆâCÑй^N;ÛßkZjó_Ëu-ض»¸°„, g"Ær¥J4R»ƒžyÁ E¢¹_ ]k²_Í£öÉlžÝ%Š{ϲ‡ß“¸(·b ‚3ÈÁäæ°/SÓµÞXk7ÌÚÍŒ Å Æ¢Ñ ³q±QÏAëÍzMçÚÎ¥âHuËM¸Ôg’ÊÁ.#•RÏ3»´œËæýØØ÷`¹9Æc> ñMî±|mm®ØÜÁµF´ò ²Fîdgq&NöÚS÷¹ E¢¹ÿ_]Áq£ØZÝ›¨]˜$»¬Ñ¸ ÜÅ@¿â°uSV³—X†?´FÓñXa&퉗&O” £Ë „ÚrO=wÔW «jšÜ×Ú£Zê2éñÙèPê ÃþùŒù YIÛˆÀ `ñÁåöºÎ¨±t‹‚*¢í÷˜É@<Æ\‘¿+žÀP¡ÒHrIíXžÔÍ߇äœI{u=»Ë‹v‘¬Þb 7”6:ex5Ä]êúµß†#2ët5êöDŠ(—쬨­ˆð¹Ùó;÷ãô»+û-NØ\Ø]ÁwnIX$)#‚2*Åsw^øo-ä3=ÝͦžeçUê#!«ìךçõwWÑþÎ? ­‘XN·òÃ`\ˆÜª©L‘‘3Éà€G¢¼ãTñ·a«¾…owuxú(~Û[‰ÐŽuWº¶i3YÙ®ÙPHþ"½ë²ñ¿öŒÞ¹±Ò yooÊÙ¡\¹Ã»0h ¸îÇ\W?ðZD‡àæ‹,®© †gc€ O&I=…z:ÈŠèÁ‘†U”äê(ð¶©¥kš½…æ—ÀŽòÔZÊÓB‡hŽDÞQp~Em¸þ"}iž³´¶ÕçþÑÒn?á!7W úƒÙ»Œ»Û>6íØTÝÆ1Ž+°†â”g‚håUvŠ0`I §ÁØŠ’€8Oé÷¶rÙ›«KˆøvÂóc+‰§Üœ¼22:ŒZzÙ@¾,Õ$Ôô©çÕ%¹VÒïšÉæŽ(¼´ @¥bÇ$¹ÎyÍwN÷WÓtÙ#ŽûP´µy™y• b<€9>”åŸØ÷ áéáÓ´]BÞüxzò ]žÙÔÝÜ´`(ÜGïܾòwpHÏ8­mKÁ–Ku­GŽÆìD’±±V»_ÞY°æûÜŽy¯DK«y'0$ñ4Â5Æ® bB¶= SƒßÒ¥ 8×|?&¯6³yw¦Íqrž€Z¹‰‰ Ü7ÉÿMA)Œ|Ãw¿5õ¯ßZ‹¸t[)b†âÊÎKÀ³ †YÏ›¸¥Ü¦w Á˜qžEzZO ’ÉJ$X"°%222;dT”æ^[–Ó"û3M¦¾´&{TÑæ±‚“)ÄRB3mÏE$ã¹Ì—Z)a§­öˆ÷vŸâ †ÿaiö[2LdaI)¹“AÃK¨Þâž8hÖiA1ÆXp1’|dgë@QPE}i?‘äÝA'Ú#2ò@|ÄË.:™y£Ö§ Š( Š( Š( Š( Š( Š( ?ñoü•ï‡_÷ÿÒu¯@¯?ñoü•ï‡_÷ÿÒu¯@ «Ém¡ƒÉ‹›ˆä–$Ú~eB¡Žz ^¾¿ZÉñœWÞ– ÀŒÉ&Ñ®³µÃaâ^]0Àv5Èiúm»j~¾Ô|/ Vð-åº}ŸIpªÆXš<¬Ðƒ¶Có}ÒO#4èóÎa’K/›&ÂшÆÒw6HãŒqžH㸚¼ëAð÷öw‡| äéo ÒÏ —çÈ"E"Òa™N20Í·æé=©¾ðüúM§„ä´Óä´»“I’;é %O™²2¢SŒä08 Ó(¿’ÆÚ]B ÷70G$Q¾ãò«•,1Ðä¢þ_Z±^U Gi¦k¾uѯíµ4»£©µu{‰•bÜrGï™sÀgœW©E –+(u µÆg±>Š( Šãõ¿Š^ ðæ±>“«k?g¾ƒo™Ùf}»”0åPƒÁƒYÿð»~ÐÃÿ’Wün€=Šóÿø]¿?èaÿÉ+þ7Gü.߇Ÿô0ÿä•Çÿ @¢¼ÿþoÃÏúòJãÿÑÿ ·áçý ?ù%qÿÆè¶Ôtû}VÂ[+±!·”aÖ9ž2G¦ä à÷äd XŽ4†$Š$T*ªŒ@+ÿ…Ûðóþ†ü’¸ÿãtÂíøyÿCþI\ñºô +Ïÿávü<ÿ¡‡ÿ$®?øÝð»~ÐÃÿ’Wün€=Šóÿø]¿?èaÿÉ+þ7Gü.߇Ÿô0ÿä•Çÿ @¢¸{‹þÔõk =w̺º•!…>É8Üì@Q’˜$u®â€+ÝXÛ^½³\G¼ÛL'ˆî#k€@îíÙ‘ósœUÛ¿êš5¶¤ñ_`¦†u(Ù£@#pp1°Ý·$“ò˜ö隷8›VñU®›9ûEÚ$¯b »½K6pÒ\¤nab n229ùêt ›Ïí=gM»¼’ðYM•4¨Šå^5l6ÅU89ÁÀà­oQ^}iâJ6ók>zÿÂAq¦µ•UˆJê9 ¿z œãhäw¬ù<]¬Am$š„Ïáû½NÎ{èmT«F£Æ±ó°‰3‰<¼Šõ+„Õ¯µë-KJÒ!½Ô®d»·šêK‹XíRËå v A¸“÷Ÿ§=MU}WÄó¥ñŸQ:}ÅŽƒëÃPÈãtà’pß).UOÐŽrè´TWêÂÞá”)–%rl€jz(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šóÿ É^ø‹ÿpÏý'jîç¶‚ê!Ä1Íe}²(a¹He8=ÁƒØ€k„ð—ü•÷ ÿÒv­zò÷þÍJ·ÕŸO‚îÚîI i;´f¡K«@f=:gØ€‚K;Y^g’Úy¢ÊÍ&HÆp­ê¿3pxù­V½Ð´I!Ký*Æé`ÿR'·Gÿ»‘ÇNÕçwþ4ÕO†_T´»½{» u:ÛÃl-¤äò|H#$Î@]Iº¼ói¶S] \<Ï…`Ëóžz púŽ·¬iÖºðÔo.–é¬/ç±Q´–n±‚T¦ÌÜ«·"N '­jG©ê–Þ)„jWwi§ÜΰY‹u·kv&,ì“5_psvð(¥Ô4]+W1KL³½1Çö˜M‡Ûp8¤¸Ðô‹ËÈo.t»î ÀŠymÑž"¾ÒF¡6—s¨yÚeˆ»š¢·û8Ér¾kJCÛÄg#É€:øG41qmqý§yöª©o'ÙSt*½e@íŠeÞ‹áâóÍ3K/¨:¤¾tæåÆJ†ÈùÏ€sÒ¹›ý_YŠë_¾‹Tt¶Óu Ha´òc(èñÀ\3ÝÏšÄAÔ`U)/5 F÷@ÔnõL¤¾ –ÓÌhžƒ å°™l’9à(Ðí,íl-RÖÎÚkxÆ(P"(öU¡Ðô‹vºh4«šðrRÝÎ]ø6rzúÖw‰îoâ¸Ð­l/ZÐÞê>DÒ,híåù9p  ÁÇnã ó֚Ʊ¨j‘è’kogå5ñkõ†/2&TTe(0¯–ÂŒã¼Ðy!‚ÚÕ̦8­ãBX¶ç=€±nü-¥\è†ÃM¶²±·–æÞé¾Ín¡$òåI9 €wÆ}óÏJânµý_Ä>Õ&›R]=-ü>·l‰ºiPXîˆÈŒ`)æêx«÷úψøišBÞ!´Ò`¹ˆ[­©»ï—Î`|±°““Èâ€;dÐthôÇÓSI°[;šÔ[ ‰©L`þU‹@ÐÓriºj)0ZäGÈ%§Þ*\JÀ‡UÕàñ5¹Õ纂Îîe†Ö;o³Ém¸Å“‡PûƒòÞKâ('ox~x¯.Sʶ»AÆC•òÎ>d'æ8郒@:¸-áµ ·†8aA…Ž5 «ô¥I^a/‰õ»_Ũ®².æÔ4 ½D †0,åŽ5e)…É@[i¸äzŠëu;½GÃþ Ôµ#s&£}«Ü)•T0Làägœœw ŠŠóøµrÎÒçûB}T[OÖåÒÉ® ï ]±¬lP«ep\qÎI¦Aâ}]4 V9§’+›]b 8]Þ$&Hc—É%äeóH㎠r(¿kˆRâ;vš1<ŠÎ‘–™WˆH—'¶G­I\5þ›¨hv‘ø†ìÌ,¯Ë^40‚îµù@®9+Óó®‡Âº…Æ«á}:öì«\Ë2²®0à;gÅlQEã¾ 'þÓKOùg,ÞTÿõÅïŠÉŸm…«»¹¹¿¿ñuÞ™­&™oei ¬QÄÍp]œÆEolåÁÉ<ô¬ƒÖpjô›;¨Ä–óÇsˆ‰Lò‚?*íîô]/Pû9¿Óíoߘ^æ•ú‚Àxë@%¾£s ”ÖVz”Wm¨ê·,c¶?"]0,æ|(PXp'>Õ4$Ö.-4]röææßJ¹²³–_°, ©4‡æ,€É°–P<¾G9õ®ÖmI¹'Òì¥ÈÒ {tm®Ç,Ã#‚O$õ&£ÿ„wCרÚwŸjª–ò}•7B«÷Be@ìJÃÑu-N?5ž³ww¾äÎö‘ªÀÖ’F®0Q”y¡‚•ÈsŒ“ŠÊñT7±ø“_¾µÕîížßÃÞr"E¡ÃJvñ¶T•Éç<õÆí­4M'O¼šîËL²¶¹›>lÐÛª<™9;˜ ž}jylm'iZkX$i¢òd/%ãçä9꼞:rhϵíb÷JÖ/o,Ô›‰tÍ.ê©û±%ÌÊX!rn!sŒñ]G…çÖ\_C«Gu²9WìÒ^9¨Èq)ÁÎAq“®ú}”žfû;vóbɺ wÆ3„Z(„°ˆ›@;FqódñÖ»dÐô˜ïôz]’Þ2…·A&ò-»Î ÷4¶ú.•gv×vºe”,X´Ñ@ªäž¹ gžôÄÚ³Gý—äÿË/]CmŽñŸ?Ì_ ùøí°zW¢Vu¶‡§Ú}‹É€±+ˆ2äí/÷˜äòÇŸ˜óó7©­(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠóÿÿÉ^øuÿq?ý'Zô óÿÿÉ^øuÿq?ý'Zô (¢Š(¢ŠË°ðö›¦ß=í¼s5ˡ̞æIŠ!9*›Øì\€p¸JÔ¢Š(¢Šóÿ É^ø‹ÿpÏý'jô óÿ É^ø‹ÿpÏý'jô (¢Š(¢Š(¢Š(¢Š(¢ŠóÿŠó%Ø×cÿ³× WŸüSÿ™+þÆ»ýž½€ (¢€ (¢€ (¢€ óÿÿÉ^øuÿq?ý'Zô óÿÿÉ^øuÿq?ý'Zô (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ *ž«ªØèz]Ƨ©ÜÇmgn›å•ú(þd“€ä’É5ÃÃwãÿ!¸°1ø7LÂ&»µûEôÛX€Z'ÂFŒqËœ¬ z%aøÇ__ x;UÖ™£kn͘¬ÊÒŸ–5!yÁr£·^£­sð‰|Cÿ¢Ÿÿ” ñ®/â2¾·Ó•ÖIV¨¡Ù[r±À䆃،Õä·†)¥š8cIe Èê ÀÀÉïÅpðŽüJ¾ÿI¹ñÝŽ—3ýë; !'†èÜÜtù­Z¢€ˆ±¢¢(TPªŒ=:Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Ïü%ÿ%{â/ýÃ?ô«§Õ|7e­jöW—ñ[ÜÛÛÛϵž"9‘¢`ÜñÇ•éß¶9æ<%ÿ%{â/ýÃ?ô«WÆšµŒÜÚÜ]æÁ²Ýµ€·i×pÅf~vüÙÆ(jë@ѯJ½&ÂàÇ’žm²>Øúm/·J¸-­Äï8‚!3¢ÆÒ™$)=À,ØçָɼE¨mÿaÃwºæúêÞ{)¼µY²—“Œc#Ê•rFG˜žÕQ5M-´ë®ºGy®Ýé¾H¶ˆˆ¡Gœ+)ÛŸ0€’¸ê¤ä¶ ÃÖK}3K¶–äùæàS)߀>m¬Tç±#ڮͧXÜ%ÊOeo*].âV€07d|ÜqÍyäWŽ£âÖ}mí§Û(¼ÙV9`Û€T lŸ—S€3ÅëwUÖÓCµmTiÆæÊææKÈbŒ›†ŠE@THBÛÏÁ s@lv‹—L·³Óãc–KXâAÀùQŠÓ÷`àÀéNºÑ4›Ûè¯nô»+‹¸qåO-º<‰ŽFÖ##ð®WÁº”úƽý£tOq Ù;”V>mÏÌ¡ê=G©kÚ¬WšµôZ—”šv§oe™å!«ùY,Hß¹¼ÆÛ´òŽ4ÕÅáí.¤‹GÓã{µd¹e¶@fVûÁÎ>`{ƒÖžš“¤u(ô»$¿#émÐKŒcïã=8ëY~›Q¿÷·Ú”³ ¿¼¶†ßËQ;‡Eä.âÀ.3œc¶y¬5Ý^K½&õµ©}­Íc&œalqÆeAÛ¿wîÔ±$õà ïZÞ¸Žá¡ŒÏ²$…FåVÁ`PÕÈïéT¥Ð4iþÍçi6}”æß}²$ç?&GËÏ¥rÿð’êéö×î%ñå›FCIr\l@1ýÔNz÷Ï<óú®¯ªÝø1ÌÚɼ]g÷w’ÅQ/Ù™cVÂas³ç(wn9Æ4é—Ú>™©º=þivÑ‚§d*P28ÍCy£èo,z…ö›§4–‰”¹ž&^r”¾ÕËê·úÍæ‹¢ÙÞj—hµšá® K?=Ê”˜= 9' [{šËÕu=RÐ5¨µõÒå±Ð„ó@‰­Ã¸”1cóavÞO€;ûG³¹’úÃM±‚{™.-àEiAç%€ÉÏZ[íIÔåßévWr1‡žÝ$!OUÉ9×û!öÞ€ SåÞÉ¿nq»Œõ®nÊYµx~TÖ5T’mB„ñ[ w¤°nGÚ…¡+ÙFç Å;™ 5Ô6qÅ<¨e2ª…’Lª&ìõl„QžxP;Rbé_o7ÿÙ–_l-¼Üy ænÆ3»Î8®=µ\è7Ú¤Ú£ÈF¹ö8 0Eå¤CPX‡ðä¶ÐFsÜdf’ g[‡ÉÔdÔd¹ŽMrîÀYy1„1#Ì©‚váå¯9ÁA<Ðw-¼3ÕoRyìüA{v5·Šiä[ˆpÄ®è^ >BÜÿ7Jèo4]+P1Ý2ÎäÄ¥có WØP28—Ú‘©¬+¥Xݬê„öé ýÜŽ? Âø…¨%¿‡âÓœ[U¸K6Dò¸ˆó1 €±ÄjýR+ŸÑ5›ÇÑ´]O½¸³{}eô¹$’Ûl¦Ù`–HŽÉW*J,\‘Ôw½MH‹R:”z]’_‘ƒt¶è%Æ1÷ñžœu«mo Ïï m4A„rdÔg?AXžÔ/&Ò/¾Õ#]ÜY]Ü[¬›UZ`Œvä(v0ì+ÃZÖ§=î€÷:¨¿MgO’îXDH¢Õ†ÃòìË”;ËÏQ@Lz »1i6)öÐVëmº<ä?6rzç­_Ú6íÀÛŒcb¼®k–Òu¯í1«\ßiSÜInÑF«Çíã`¾V‘“ÆÚ½6­â«]6sö‹´I^ÄAwz–l᤹HÜ*ÂÄ(Üddsó0ÙÃá­Þ ˆ Ñ4Ø¡¹ÇŸZ¢¬¸9€n}jxt2ÚÒkX4ëH­§ÿ[ @ª’pæ`ðç°³´ ›Ïí=gM»¼’ðYM•4¨Šå^5l6ÅU89ÁÀà­oP-KÓDbÃM³µˆ TØ‚À`q«Ÿ]£Ò­Ao ¬ ¼1à ,q¨U_ *J(¢Š(Ì~êi£| Ó5ŒÉä¥ÁXÔàÈæâ@¨©bã]ŒÞ(²±×¤Òõ9í,ŠÚÁ2Ë5ʨ‘äyWbîÆHò¿ô®ÀV“Þ~ÏZZÛFÒÍt‘(ÉÃxÒíçf?é5Ý?Q—ÄZ•õ®ƒý¥m¢Çe™#M¯¾bC „álz`p¾ž#³Keo¤‚ÊßL¸Hây‚£nŠ92IÀ_õ˜ÆOO|U«sH´°ŠþçU±†Î\yw\"Æùé†'¸¨<3¬é—±^5£j"ÏP†o)e@×*¶ ‘w0ƒ‚pÄt>Ôý7DÕô}BÓYm®”µéþÏ‚X·Úyò«©Rì¨N†Ãun2(ªÿ„†Õu{ËY^­m¬a½70VF•~€+9Ï;½¹»}©Øi–ŸjÔ/­­-²q*Æ™=9'Æë>Õnü]½–ÞÚÎÓ|’ IÝrË×Óz²“òçþú]ÿ.¯%½‰Òãœ?7?g™Ñ666y¿»Îâ ç[MB6Žquu Wdbçw\ì~뀃¥tTQEQEQEQEQEQEQEQEQEçþ-ÿ’½ðëþâúNµèçþ-ÿ’½ðëþâúNµèQEQEQEQEçþÿ’½ñþáŸúNÕèçþÿ’½ñþáŸúNÕèQEQUÖþÍì>Þ·p/,Ëö òö’Ûºcæ¨Zx¯Ã·áÍž¿¥Üöïòo#}»˜*猒õ'¯ES»ÕôÛ¯5Kan‹$Æi•<µbB³dð z‘T‡‹ü2ÖMz¾"Ò ªH"iÅì{È$)mØÉœ{PÍ ¥åµý¬wVwÜ[È2’Âáч±„êúhÕ–uA¨Ü-<åóHÆs³9Æ9é@(¢ŠóÿŠó%Ø×cÿ³× WŸüSÿ™+þÆ»ýž½€ (¢€ (¢€ (¢€ óÿÿÉ^øuÿq?ý'Zô óÿÿÉ^øuÿq?ý'Zô (¢€ (¢€ à›S×ï|=ªø¢×Vû:ZItmôãfŽu"F+¿sydåXÈàãžö¹«¯Y\½ÜnÔ"Óï%in´è¤QÌÇ/œ©pýà¬ÉÈäÐ3ã{ø˜Ý.¿Ùº{À.'kœI¶H£²¦Îv‰9‡Œžz—Ä[-?\¹±"ÈÅiq´æKõŽà³í9ŽeÕwŒœŽ€qR'ƒÚ÷]צ½žî »Ø$[h¤O*æ8à„ Ã”oF¹œŒV»øuWUšúÓS¿²,·6ðü¹œ¹;‘™I  í+œzÐ}§‹®§¼‹ÎÒ’+u9ôÄœ]nrñ´ŠfÀ6Ÿ,½OB9ªþ2Õ®ìµÝÎKS²·¹†åä:uˆº•Ù<­£iŠBÌÙ ­l§†¬£†„³í‡Q“Q\°É‘Ý܃ÇÝÌ×Í[¸Ò ¸ÖlµGyöqKjÚD›7gŒçäçÖ€8û/j|ZE·ˆ Ó£»¹h!•>Ü©wºV ­öm½2Ã8lŽN0*î­ã‰t«[ÌÓ zuÔ6†â[Á™$±ÆË€W n%†ÈÏJ½wàëK»Ë‰õôQ\^C}-¼mGš"…I% c÷k‘»€jÍφ,n“S=Àkû˜îÙÕÀh¥#Td8ãRžsÎ{P·ÚôC••Ý욂ؑk¨‰ ¡yC‰Br0„´ÏŒôzªÚ½Œ’Ën-ç†â[y¢Y7ªº1Sµ°22^‚¡ÃÙ{)/5[ûélî¾Õ“ù@îòÞ=¤"(Û‰ðÎ9«šv™˜·+ HÂââK—ÞAÃ9É¥q>‚[ÇÞÐu£¹Òîn/.g¶‘AY$†ÆOrfùzò z%qô[ë›}3^Ðç´ƒ^Ñ®7Ùý¬â9Ä£Ëks’2eT¹Às¸hxWÇ:/‹’T±–K{øÒãN»;¨ 0Sº<“Œ‘ÈÈÉÁä:J§ªéV:æ—q¦jvÑÜÙÜ&Éb~Œ?˜ à‚90E\®Å9i¯_ž–;ßNŒ‘…’ < ï;g TnÂáŽà ¯Ìr¾&\Z|?Ñín¼-â½NKxŒ"êÃLBèŒÊX0ÎÕ §Žªs“Íuð´ÿêBñÏþ ÿû:ê<+áë x_NÐí[|v‘/‚<Ç'.ø$ãs8ÏÀâ¶(ÏÿáiÿÔ…ãŸüÿötÂÓÿ© Ç?ø'ÿìëÐ( ?ÿ…§ÿRŽðOÿÙÑÿ Oþ¤/ÿàŸÿ³¯@¢€<ÿþŸýH^9ÿÁ?ÿgGü-?ú¼sÿ‚þνŠóÿøZõ!xçÿÿýð´ÿêBñÏþ ÿû:ô (ÏÿáiÿÔ…ãŸüÿöuå<[ªiž#‹ÅžÓÁ ÷ˆ…Çá\o„¿ä¯|Eÿ¸gþ“µlë×—¿ð–hšU¾¬ú|v×rHcHÙÝ£0í ]X1éÓ>Äh&ŠÍâ–ÖîgŠC¹¶´‰!ÚbF*ÎY·Ä•\`.ÆI7ÆŸd¡Ú[€“4éˆÇË#d³Ž8c¹²zÇÖ¼ÎÿÆš©ðËê–—w¯wa`n§[xm…´€<C!‰dÈŒä Úñ>µ¬Yj:ÔöW’%¾™¢Å~–©dK)yó¹™IÙˆÆ@ ñÁ䩺Ð4kä)w¤X\).ÄKlŽ b GrªO©Ò¤¼Ñ´½FÖ+[Ý6ÎæÞ,ážtL 00+…›VñU®›9ûEÚ$¯b »½K6pÒ\¤nab n229ù_I¨M¥jú]Æ«s'صm7ʺ1Ä$ØòÂpØM§kAÚ: 眀w-‰»­ÖØÜÄ Œaw r£c‘€ùÿ{=é²élúŒzŒºu¤—Ñ Grð©• ldu® ÛUÒ/üO¨[ë2Új–jñI Gí; ¶W2£+q³n¯J³w®x’ãÄz¢iðݘôëÈ X좌¬lÍ)‘Ä í´®ÀûÜŠî1g¦ÚÍ. µ¶MóÊü".Igv=$’O¹5—}á:÷S³Õ ‚ÖÞî+¥¸’â;uó'YB–8ùÉÏJå5oXÓ­uá¨Þ]-ÓX_Ïb¢;i,Ýc©L/™¹WnDœOZÔSÕ-¼SÔ®îÓO¹`³ënÖìLYÙ'j¾àç íàP@Úf†šºNÖ:rêræUÄ‚gÛ€Xn8Ü£=²=j[}J³–æ[m2Î .³ö‡ŠS6¾@ùº÷¬?^êk6–º\°Gq.™}$~r®ß5L b2Î}ŽFsV|)5ÔW¶·wŒ—¶³š;ô€Iå 0Œ¤ƒ×žhÍ·áÈt”²ºÒô¨ôÕ•vA-¼b#6»‹0¹'Þ§Ÿ@Ñ®£‚;&Âd6B²[#×ÑAa^}ö;¸ü©•Õ.%wñ HÖdŒ¬L5AóaUI'‚A8ôÅ[Ôuí{MÔCKË»ÆmJ8ñ#¶[[™vû"ݹHއ¡8 úïN±¿²6W–V÷¤`š%tã§ÊF8¨ƒ£5µ­³i6 Fßo¶M°·\ ÆûŠ­á™õI´“ý¯¥ÌsHŠd1otå."%c€q‘ÐgÅéž,¿¶ðê:óÝ&£¦Í5ÖÛx¿ÑÌqîóUA$7ÊCdçJôS§Ù ÒßÉi|ã–6™7ïߌcvÿ›=sÏZ…’ª¨´€*LgP#IqÇÞ%˜“דë^xþ"ñ «éßj½ŠæÓ µ­šd>S†å í^2|ÇØÕ­gRñ$:åΦÜj3Ée`—Ê©g™ÝÚNeó ~ìl û°\œã :_ƒÖË_}Vá´öo.DXìôñlÈT³Êw7˜øP3ÀäñÍk[xwD³·–Þ×FÓà†fV–8­QUÈ9€$Fk‘¸ÖuåmkQmA¡O¾³‰,V8™ É»H¬ÛKelF¨À­OZ̾0ñdÇP¹hþÝû;,{m  ä&î>èù±ÎNMtïm—\Io4!„r2É»®Qœ â©Gý‰u«Î±g˩۲I0]4giUfþ v³Of#½rš–½ªÅy«_E©yI§jvöQéžR:¿•’Äû›Ìm»H(àóZ>µšÞ e忸¹ßªÜ²¬`)0$mU9¬@ÉükÍ­tûݺRŬÝ“ÅwÈ¥ã„ùX›™@Aó“ódzcŠÒ¹ñ¹›gb³ÜOs&±>ž÷GÌÉ‘—M±;Tr1× œ éü7ám;Ú]­¼6Ö­w¬vÓ^%ºÆó„P2ÄdöèI«VÞÑ,–EµÑôøWY$Z¢‡emÊÇ’b3U¼=q«K¢HuT1ÝÅ$ˆ9s ?#H"b¡±Œàö<•Êîk¶:]á¾¼¿mZÆ/î-åŽÙ¢’çÍòZ%ÎÒ¡ÀÝóß ‚–ðÅ4³G i,¤Tø=ð8©+‚}kWÕ Œö¡¶³Ôõǵ·xâñmä®å9-$LÀœñ·¨È)¦êšìsØOu«µÌgYŸKxM¼j²F†P²"L '/û=躷¸†îÞ;‹i£š TûXî¥\DÙÊ‘¥\´ñŸuá[È5 kA×bkD…l4µÄ®Ï„T?½~YˆPp0y®£Jñއ­MVwRî–#4^}¬° Pc,†EPàd}ÜÓ£ñn‡7†‡ˆa½2ée‚‰£†F$—òÀq;¸Æ(Ï.VãHð³a¬ÜÆ©,—QZÀëžmŒé f (”rXÞ€3¼kiªØ]lœ:Œ¯x±±–ïV{#)R3žwI×''ŠåðÕÖµ~ßc–æîòrús²ÙÊ€ÇÌ Üв"30áCdqœwã-+E¹”jQ£Î-Ñ_JºYB¥€T1înŽ@#ŠÓÒõ[-fÈ]ØMæÃ¹åYN ²°H=ˆ€-FÛâFÜ­•rô>ãÚEçÿÿæJÿ±®Çÿg¯@¯?ø§ÿ2Wýv?û=zQEQEQEçþ-ÿ’½ðëþâúNµèçþ-ÿ’½ðëþâúN´èQEQEQEQEQEQEâé~ÐæÕõyü«xøU^^W=v8?‘$€ üKã;\A¦G—úõâc¥Ûÿ¬œçfÆ#N¤»`¬Fv‘Xþ ðeôz£ø¿ÅòGuâ‹”Ú‘¯1iÑâ(†HÎ ¹ê@',Ο¥xSWñãÛë¾>Eh—iÓü8¸B»p¦ãŒÈýÓŒr™YâOøkÅÞY×4ˆ.äfËG 8]èCmù‰Ûœd箂ŠóÿøR_?è^ÿÉÛþ9]†¡é~Ó’ÃH°‚ÊÕpvB˜Ü@s¬Ø,rN95¡EQEQEQEQEQEQEóÃko-ÅıÃH^I$`ªŠI$ð椯;ø­u}o£ø+Ky!»ñ%ÃC%ÂÿË+hÀiß\¤|¼†]ã©Ïø#ádžüeáóâ/øVÒÖ]BâI­ ¶’h<»bqdB‰œT]¬rI'¬±ø?à>ò;¨|9È™ÀžY&CG(ìTõî8ëÖ»H †ÖÞ+{x£†$qÆ¡U à8ÅI@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@á/ù+ßîÿ¤í]>«á»-kW²¼¿ŠÞæÞÞÞx ¬ð ÌçŽ<¯Ný±Ï1á/ù+ßîÿ¤í[ZíÝô¾#°ÑíõFÒá–Ò{¦¸HãgvFŒb•,xÎÁЭ֣^”7zM…ÁŽ/%<Ûd}±ôÚ28_n•p[[‰ÞqBgE¤72HR{€Y°=Ï­q^Ö5j–> ÖöˤZ^I &&‘䘖RB2ÆÏLÎuu»ËÙŸÊë$‚+TPì­¹XàrCAìFjÌÚuÂ\¤öVò¥Ðá^%a(vGÍÇןé.Õgðæ£{w¨Fd‹ÃPßÇ'–оq7!œqÈù#àñÀã“™ÄzÁŠóS§–lom-Nò£ÅÀ‘a$±#~æó[nÒÚ8<Ðq¥ÛÚ½¬:mœVîT´Iª1P’ÁÀUÓhô¦ÝhšMíôW·z]•ÅÜ8ò§–ÝDÇ#k‘øW¨]êZ%÷‹¯ìï®ßVµ·ò¶@Q±[¯™óåCm]λ<“v=KÄ¢æÓI»¸¼±K»ÿ*;땵k‘ä+¶=Ñ,˜¯Ý=3Íu6º/‡™ïe³Ó4²×à»x`2ó‡IóÔƧMI‹R:”z]’_‘ƒt¶è%Æ1÷ñžœu¬/´£CÕ \Ç<«ª^<€È•†HœãÞ¹ëËÝNx£MÖ/uª®‹%ä‰lbÚQÁ0´kÊ1aþlzhÑ.´û+ßøû´·¸ýÛEûØÃüËÈèv®G|J‹H´Òm4èÆ‹oe Œ¿½O±"¬oŸâx9ãšçtÁª·Š¿³›^»–Ê×Nµº!¢ƒt®òL,#.Ô€‘Îp4ýg_¾Ñ|øµv¶û7†mµ‘[C‡¼ìäáO–UDZäÐF‹¥ ‰î™eç\2<Òy ºFBKd@ ž„Sît­:ò;ˆî¬-gŽçzË °— À›ï\V¹¯ê²Å«Ü[jÃKv‹üQˆ£q3¸å·‚v‚@\“’xbÏVÕ¢ñ£ê·—kcw"Eiöu·kwc;dãÍWÜä|¼”ØÙØÚiÖ©kck­º}Ø Œ"/Ðbx_ÃZ.™áû8í!°»/e¼—Ñ@ƒíq„Fw)¦HªºÕ¬ÓüDðûG¨\ÛcxvıØ{rA܇®yÇ?(Æ9Î/îµ3KðŒW“Oe}¤04H«–‘•(@Ü~RAÜNO#(µ·Ð4kDd·Òl!FØJÇlŠÆÜð·Ì="©húNª#mSM²¼åÝ@’lõ#p8¯3Õ5íJÿFÕìÚóS’ÇPðååôÞEjŒBÁŒG’–Bnô9Î;MnÖx¾j‘Nêi?³¥arër6•ãtÎ;çšÖ³.«g,ÖBÂòÖáÃHðì‘%tÀ‘HÚ£Ûhô¦²hqjSjNºr_ÄRÚ[¢J…¶íŸ¨Îä“Îáê+Š›QÕl,o`‹_{eÑ´hoc3C 7%¼Ã‡ùîÆÅA³i瓚mäÏqgâ9¤ŒÆòkšK²ªH²8ü(¾—HÓgÔcÔeÓ­$¾ˆb;—…L¨=c#­X†Þpâcˆ;™"…ÜÄä±ÇRO$× k®jóÜX^Tÿ§ê·siÂ(ñ¡”S·~õòÃ6âAð8¬H¼q¯ÜG.•x£Ò!Ù©æ0î29‘ø<+§ZôvÓ4;]E/ËO†úâa²s,²Ê±†ÆKlßïݳV&Ò´ë›I­'°µ–Úw/,/ ²HÄä–R0NyɬÏÜÜCy AÆ/µj&"³û<Í‘¸UN}±Ðs¾Óü ½M¤ûE´ ¸1®Ö(1mUÏCÁË{ÐOiaeaf¶vv[Ú¨ C a×å'‡mm4«Ë]ÛNÒfºic²R¾„•R»Ž ÆOô= ^j3ÛøÇK²ó‚YÏaw,Š@Ã:<NzŒ+ÉÆ—Þ•«k:ä~u‰-Åþ›sss40ÄZFF„!”¨ÿX{`ƒô ¯°Ñ¬tí3N°†Ý=-‹¨&=¨P0=›i##ÔúÓm±®üµ´ûÜ‹Ôln\¶&þñßówçžµÆxFkícÅk©ÜêS¬¯¢Ù¼±F‘ˆå"K…9Ê#w·\` ü w5þ§åË+O7†ôù$e@ ±{‚xô€:Û= HÓ¤y,t«Wt»AnˆYI1Ò–ÛCÒ,¬ç³µÒì µ¸Èš­ÑRLŒÊG×#®ø’úÏ^ØÜêZéZØ\FÑ[ U24a—$‰‹â@À®Fx#Ç{@#Ðô˜µ3©G¥Ù%ù7Kn‚\céÇZ*ýçÿ¿äè_öñÿ¥Wsyg¡e=ÔbKyãhäCüJFü«†ø%ÿ$‡Bÿ·ý(’ºOÞOeá›—¶‘¢žg†Õ%^±™¥H·q¿?…\»Ò-®+•¶´mFÚ2¶—w0 šF3œ†Ç¨ 3ëYKáWÂèbáN.£»šcÄ®.wùsÀfc'÷ÅQÔµísKñ&«­Œºu†• Ð…®ŠÊ~i·ýÛc储ùAÎXâÎ¥ãE¶KÉl,~ß ¸²Öm‚G¹* àôVWÏû@{ÐÒh:4zc驤Ø-ƒÍj-DÇÔ¦0*³gci§Z¥­¬¶é÷b‚0ˆ¿@8Éê>=þÈ‘ìu K;mL\$(²ß„¶*èÎÌÈ Œ# mÎ@æ·<7¯Ãâ='í±ÁI^S Srœ®8e<p8=â€#ð×…ôÿ é–AolבZÇo5â[¬rN@ËÏn„š¹q¡é–0ØÜéV3ÙÁ&Þ[thãÀÀÚ¤``zW- x‹Rÿ„gÃ6v¶¿Úz¥Þ–·r½ÕÑŒlP€³>Ö%‹8ÀÇ<äŠ|ž=šãNšûJÑÍÔ6ºrßݬ×>SÆ>#Qµƒ8òÛ<Óæ€:{ÍJÔLûL²¹6ç0™àWò¿ÝÈã éIu¢i7·Ñ^ÝévWpãÊž[ty¬FGáYzf¡3ø®âÝÌztÑÆÎXDùd`=pǹ®Ž€3#ðæ‡—2G£iÈ÷JVá–Õ˜Hs˜zX¼=¤[Áoom§[[[Á8¸Hmã'˜Š®ëž{€{ Ò¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿÅ¿òW¾ÜOÿIÖ½¼ÿÅ¿òW¾ÜOÿIÖ½€ (¢€ (¢€ (¢€<ÿâÆƒâ_hv¾Ð"mï%/}w<Ê©G†D#ŽçÁÊŽ6`ðƳü#ð/ÂÞÛq©'öÝðÏÏw¯ÞE’}âܨ#êPŸøKþJ÷Ä_û†é;W WŸøKþJ÷Ä_û†é;W PEP’ÅámV?‡šYGÕ.u‰m…µ­Â¬q؉°²±ÙeÂùŸqw55æ•®Á§ëºAÒZÒ»‹Ë?ìök”ˆ‰¢I@c€@dÁR9cȽRŠóæÑÍœÚý¦¶š®¢·[^Å©[@LÇi(ãd …^CƒÍSÔ[[¿ð~· 6±uiÝ›XÜϧ”¼eÆÒ(F ÆA)“Ïé´PÞC{¬Ã£Giªx‚i"ÖG»ºÒ…¼–ëäJ2 U+’Jž[¯"·ügs¦[êzuâL÷1_I#Þ:`^ 0âAü9ÁÚBð žÅt´PEP›übûgöw„ÿ³¼·ÂKgö´gËó1&Ýøçnqœsбÿþ¤oü›£âŸüÉ_ö5Øÿìõèçÿð–üCÿ¢aÿ•ûð£þŸýH^9ÿÁ?ÿg^Eyÿü.¯Gû»ÍV{+¥âk[‹ĸûÈà!È8'‘Ö· øƒàÛ›x§OhÁ$@ê$½3ʱO±ŽõÒVþ ð­ÕÄ·ѦžW/$’XDÌìNI$®I'œÐ¥ýž§gå…Üv²gdÐH$FÁ á‡øQöÏìëŸìï#íÞSýŸíòüÌ»ñÎÜã8çÇß|ð¡y%ÔÞ$|dA, À„F :võë\ÿ‰üá¯hsjGÅž+Ðô˜xƒOÓµV ¼ó²%`If;›“݉ € ø×¡x¯ìšv¤³u¹vÇå°>Lòÿ«nqœ•°rÁAcÍhx·þJ÷ïû‰ÿé:ׄhÿ|{â‰^öêÓì^~ùZãU”£Èû°w.MÄäå”g®yô½;ÂÞ ø‹ðûN¼ñÞ²›õ#ÎM«n‚Õ"XÇMØ’@=²Š( Š( Š( Š( ŠŽyáµ·–ââXá‚$/$’0UE$’xsRP\?Šüoyk®[øW–°j>%›J³äXÃÁ2LTäd…<ƒÝUóüCâ}SÅ÷ƒÃ^Ÿ÷2ñ¨xŠ/ž DÀ%"qÃÌCºxÈä²vðÆ—á›3Ÿï¥ææî_ž{§É%å“«±,Çž™8q@~ð<>¸¾Õ/o¤ÕüA¨97zœÑ„f\ðˆ¹!8°ì/YEQEQX¾0¸¾µðn³q¦ï±ÙJД`ÁO zŽ£Þ¹–°ÐôO·­ÅíÎ×x-ylbrï!þ<­¹²AÇ<РQ^yáŸêÒØøfîãU:¤šµ”²On"B2 mɱA7ÈÙ$e†1Ò³í¼Mâ·ð­Æ¸ZëÊ›F¹»ó&[O* –-éä„båAÈ"@OLã‘@§EszEΣ‰&Ó/u½ì"» $H†7.ÊÁvòð0Hõ5‰ªkÚ¥µÿŠ.cÖ6®“wlXyQâEx¢%•Üw30\AõPEpPx’øø»MX.u ôÍBúâÏý"+e„ÒSû­¤M•h¶’à‚3ӌ҇[ñ xKÂ÷O¨^]]ë†!,El0¼˜ˆ8TÜÄó“ÐàtéTWgyâkÍSJÒï/®4ã$WÏ+ˆíži7„DÇÑ[@àóÀã/…µ WÂúuíÙV¸–ee ÂqÛ8Î(^Š( Š*ž­%ô:5ôº\1Ϩ%¼k‡ ò…;ò8-Ô}E\¯;ø2ø·ÄºïŽ˜IäHÿÙZVèÙGÙ#!™Ô7 $$ò2¥Jç¨zÇÅ=/Æ’ËG–µ½zTÒ>Ãrù6ï7ÈîØ!ŒaIè<•ÈÎTz†‡£Yø{C²Ò,e­¤Kd[Y°,NI8ä’hBŠ( Š( Š( Š(  ×Ú…–—jnµ Ë{Ku82ÜJ± ?R@§ÚÝÛß[%Í¥ÄWH2’ÄáÕ‡¨#ƒ\·ˆçµÓ¼g¢jz»$zTVפòñ,cÚÌO ”ÇÜw®^âöÞ+ã}o}=‡‡oüD˜šÞF…%Qg'šÁ—ŒÈ£-Ó*[=èÕè¯/¼Õµì g·½wÑX–/·O$­B1B×*¬êžgʸ 7sš±¤­Þ©©èvW:Ô“ÙI¡"¶©Êë",ÃL3•ÞÃw_s“H¢¸Ÿí+Ù> Ýê u/ÛSG…Àm²oXÛ‘Ѹ#½cK®Û[­×Ø5íCN6p ÇmBDò.eQº\“‹¡z òéôW•éwך“[iꩆ eñ'ÙƒÚêRÌZbÒ”óÈWuÜO'‘ÆÓïï58|UyfuH,§‚êôä¼Ö&‹Ì€,yÄ\n;ÁbųýÜf€=FŠóË.âšÏR:ü“MâK»FI.]¢ò<ÙÔ&ÂvàmR21ŒãŠô:(¢Š(¢°uWP]jÇDÒ²Þ\Ã%Ì“Ý#:CRv+)f,êÜ:@ÔW#Œ¦²–M;U²yõ8ïÖÅWOQ¶bð™‘ÀvAU ‚NëŽjùñm§Øb•-/î[¦³[Tóüå²òÛKnÝ·ç‘@ôW4õÄK¨]imâg¶»U–]bÆÙ¯ˆÄ[#I»œ1#¶HíO—Pñ#K}¦Ùê¢Âýc–æ¶[©"0(¡ÔD]Y—<”Žý@:?Âz]¾aagg¨½œF$š{e'®Î3éš¹s¦è\Ū]YiñÏn8®å‰F ÀPädrp=놗ÄúÞ«8‡B›Q•"Ò⺆DŠÑZâF. ˜JË„"09'‘Å3_Ô5MOKÕ..µg¦¥ekýœ6FÜÐ9%±¸±.pC€8<šô´m.âîK¹´Û9.dˆÂó< ]£=P±+íҢú:{ØE£iñÙ;kuµA7©\`ž5âËë»It-u°‹ÝMm¦”"1(a•¶À€K*àã®:Œƒ“ý»zúkYûùo«-¼öÛ™®B)sþ°yJ@€2‡Šìm¬,ì­µ­¤@I&(£ §=xsPXèzN™Ñiú]•¤sÿ­[{tŒIþðg©ë\F—¯ëšÐÑ¢„Öå¡ÔþÒaŠ$ÆÞt;:+Nvåy8ìE+ox­ü+q®ºò¦Ñ®nüÉ–ÓÊ‚e‹zy!¹PrÓ8äP£Xhúf”Ó´ëK0T!ð,yPI匳«ZlVZDrIe µŠ¸¶H¤#@D`ŠT|ÀO½ŽõÅxŽ]M4OiWZ¤×Jþ{µsjÈø:®î\°çæô†îßU³Ö5‹‹=~äKiáë{:Haf•ƒÜ²«aìàƒ´<|øIâo ¤p+éÐ@°˜wI§¬³D§‚a°œq÷[µjÁ hö×âþ*É/BíBóqŒc~3ÓŽµÇjÞ ñ æ­%®”—q´:d7‘­°¶+$’oÿYç°>XÚɃÉÉUèu]^[^{¨,îæXmc¶û<–ÛŒY1Èpe¸? íàPM-¦•®Aks-½–¡ ‘=´®‹*ƒÔ:GЊ_³é–FÆ?&ÒÜǘ,×j¦ß—;#¾U<Ëí\®ë)¥h:¥õíÔzT–VfW±ŠÛh•ÎÎF]ÁNP+É®·Äw——z Û¼içê'óWìó7SÓ•^Fæhõ¶ƒ£YÈÒZé6;+#4VȤ«cp$‡>¸-¾•§Yéí§ÛXZÁdÁ¶ŠXÈo¼6Žrsë\ï„u Eî¦Óõ»›çÕÞ9Þ)ÖßÉÁ$…¢”$‡ù¸OQÖ5›3ã-N;Ù$‹F8µ²G°Ÿ²Ç!.vî 3–á‡~HÀ]Ö¥ßIo%Þ›gpöÇ04°+˜¿Ý$|½J™ôû)<Ýö–íçH’˺0wºíÚÍÇ$m\ÈÚ=pñkå¥Ïö„ú¨¶ž8­Ë¥“\Þ@»cXØ¡VÊà¸ãœ“PXøZº‘ty¯n-%:ÓX5ôñۙѰœ) º0±ÚÀéž(¶[  kíKia­q4F‚yv†çˆP}2*Q¤é£n4ûQ¶àÝ.!^&9̃¾r~n¼šåµ;é|[áëXu»„™tûð÷¢(Œ¬–ݶl8ÏËØð# ø£WH¢³Bæ.+œÚ%¨Iåf‘KH&`DyŒpœŒŸ˜q@•yö$Hî/~Ϋ£’lœ  ž„î+ÿÇz«‡ôx^7ƒMµ€¥ÁºLb0eÚW{Æã†<œúõ¸=PÕ5=/T¸ºÔœv𕕝öpHÙs@ä–ÆâĹÁ àòkÒÖXÝÝEgLPrW<ŒúPºe†¦ˆ—öV×koEž%+zŒŽ 2ÎßL+ØÃi¶×Ì· Uý×Ì ÇÝù=Wž•ÇøMÐõH5 S]ŽÚ]bFá'šá±%®ÙXD¨Äæ5ØŒœçœÕM&îú[ÿì{}Q´¸e»Õîšá#Ù.È<Å*Xñœ‚9 èhºPšÖa¦Y mïä.èAë°ãåü*km>ÊÌ©µ´·€¬K ùQ…Äk©Àû£' Éõ®ÛÄšÔöºN³ss•-½±‘ôô“Íw ™V@dÙM¾_ õ«gYñ µ[Ķ±Ô ¶1¢Úù&&³¼›ØK¸‡m»¼r(¬›CÒn/~Û>—e-ÞTùïnŒùR Äg‚˜~Š(¢Š(Ïþ É!пíãÿJ$®ÇZÓYÑ®´öÄfO’P2cpr¬røWðKþI…ÿoúQ%zc]i,šŸöäs]µÚZˆfµ¶ò‚Ý*îeSæ]±†^¼œW/oà»›o‡CHŽ êæþÞæhÖaº$¡óŒÇ *Œàãµz ÍÿÂjwÎú– ú‘nQ-™!@nÖa·nâNO5·ck%ªÃ-åÅã‚IšãföÏûŠª?*ÍÎZÃc¥ÛÙjöré¶ÆÒ¨<ƈ…ʶä*s±NväÆ+ Ä~’+Ó¼?e©/Ú4á`ÏÌ+ (ÜÏó™Æö;£ŽH5èPN›¢‹JâöI¼ÙÞXÆÜlŽ0N=ÉgbO¦ÑÚµ¨¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿÅ¿òW¾ÜOÿIÖ½¼ÿÅ¿òW¾ÜOÿIÖ½€ (¢€ (¢€ (¢€ (¢€<ÿÂ_òW¾"ÿÜ3ÿIÚ½¼ÿÂ_òW¾"ÿÜ3ÿIÚ½€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿâŸüÉ_ö5ØÿìõèçÿÿæJÿ±®Çÿg¯@ Š( Š( Š( ¼ÿÅ¿òW¾ÜOÿIÖ½¼ÿÅ¿òW¾ÜOÿIÖ€=Š( Š( Š+ƒÕ|q©j>%¸ðÇ‚lm/õ DÍõýÜŒ-,›<#mw8a…#×k…ï(¯;ƒÁÿn-â—Ä™öxí4¨Wl epü@àd7¨*q»€é_4K„»·ñ&›âXÍeyf¶LØ Ç‘¼€Ê £9 öÃøýã/ì_ Çáë9¶ßj¿ë¶6;p~láÎC(U?ê#øµá -&Öy4ÝÙ"³Õõ'ßw~Ë ™ÐXüÌÇæ ?2 oÜüjÕ5Oê!J¿†àÚ¾‘ög™ìQxT}ì…I!‰ÀÁ;r¯w¢|𶃬A©[jãMí£í¢.ªTüÑ*8àöaï‘‘@‰¥iV:—o¦i–ÑÛYۦȢNŠ?™$ä’y$’rM\¨áž”/±ÊÙ #•аã¸`Aˆ"¤ ŠåüWãøGå·Ó´Ý2}k]ºÃC§[6pS,‚#ŒÍÁ>ÁˆÇÿ„wâU÷úMÏŽìt¹ŸïYØi <1ãµå;Î@ÉÏBH@Eyÿü#¿¬Òm¼wcªLŸvÎÿHH!“<ÏÞ0F:àšØð§Œá –ãNÔ´Éô]v×-6rÙ&=ÅD±¾’2F7/û$¨ªZ&“¦ÜËsc¥ÙZÏ7úÙ`·Dgïó2·<ðÚÛËqq,pÁ’I*¢’I<9©(Ã^Óü7¦ZA½³^Ek¼×‰n±É8E,G=ºjÊøwDIî§]OYnÑ’âAj¦VûÁÎ>`{ƒÖ´«ñMׇtM.}wÄ&/9¬íäXÒ㙥n#È9ü£ÊHV- [´clùFí ä.zã=«&ßÂú|zåþ­somusqt·I%º—·"ã±ÉçËÎF:ã¶kšÿ‹¿ÿR7þMÔsø£Ç^·—PñVƒ¦ê:Z!y§ðüæZªŽKG)Á$r¤m ÄÐjš“ñ¾K²[ÂæCp¶è$ÞA·c9Á#>椓JÓ¦ÓF›-…«Ø-Z1Ìc1I¥j¶:æ—o©é—1ÜÙÜ&ø¥NŒ?˜ äypE\  všV`°­žŸkn VH„0ªyjÄ À%T:àzUˆ-áµ ·†8aA…Ž5 «ô¥IEQQÏ<6¶òÜ\K0D…ä’F ¨ d’OÎhJ+Îã×¼_ã—˜xb(ô _ë7öí$÷JT2¼0aé—ê®ÃŸð‰|Cÿ¢Ÿÿ” ñ —0£ Þçž+꿇 ´¿‡Ör˜¤ûn§>D×ÏÂS9«“µxòry'…Kmká5ºÙê]¦¥á¹nYµM&ÐÅ5±`]åžlt8TŒwÚµêO Õ¼WòÇ4 xäƒ+©Ásš’Š( ŠáüYãË;X_ x_KþÛñ,‘4­n$ ¢mÈyXð2Jár2än]Õÿáø•}þ“sã».gûÖvBO xàmyNó2sÐ’P Q^ÿŸ¬yÓ¾!ý¢?ãÞ×PÒã1W¼äÀÜy=hÑr9ÀᔀEz%çÿñwÿêFÿɺ±¥øòâ×\´ðïŒ4¿ì}ZërÚÜÇ ’Îô®îߪ³‘ €T–€uº®¯£Þé— ë å¼–ò4d êT‘Fp}*Ò¨DUÅ-QEQEQEV.±¢O{¨Yêz}êÙj6ˆñ,’CæÇ$o´²:nRFQHÃúÖÕÂj^Ômît™íï^}RãZû]ÕïÙ³mµ™Áùc*cv~o½“šµuà8ï´ØÖêæÚçP[ç¿i®l„<Œ¥ ˜K}͸nÈÚs]Îi^]6ûO»c´‚æ&†ÆÈ[ÄæV‰· vãÊÇSœõªúž‰6ð·UÑ­ËÞLš]ÌQùqÒ±FÀ 2rIÆ9¬éþ$6¥q-·‚´ ¿<Vk˜å[kE*pÊ'q‡q”8PAVÈ ½Õ!y5a&¸òb‚ôM¨#YFYSï7•PØ*Í?Ið*éwÌ—VÈ©ªÿiy6¶BÇú)ƒb¨cÎìóéÏZ“@ñ펭ª.‡¨Z]è¾ ØXé×Ƀ _¼Ñ8ùeL†Á$#`WY@…×-¥ñ Æ©zK­ÔÉ<Ë{¥­ÄªÀ*Ÿ.MÃh!AÁ ƒ’:Õèü/åÛÛEöÌù´Úž|¯½æI#ìëÆ<ÌgÛ§5ÐÑ@Q@á/ù+ßîÿ¤í]®¡¥éú´ JÂÖöÛ„w0¬Š®kŠð—ü•÷ ÿÒv­zò÷þÍJ·ÕŸO‚îÚîI i;´f¡K«@f=:gØ€ ßìËð o&à4~Rí 7 sò€9ìíU_ÃZ š|z{èškYFÛÒÙ­Æê¼þÿÆš©ðËê–—w¯wa`n§[xm…´€<C!‰dÈŒä Úñ>µ¬Yj:ÔöW’%¾™¢Å~–©dK)yó¹™IÙˆÆ@ ñÁä©»Ð4mB("½Òl.c·&¶GöAt)דwt·7:]”× ¬²[£8äHÏÃÍ«xª×Mœý¢íW±]Þ¥›8i.R7 °± 7üÇŒ/ˆ$Ô&Òµ}.ãU¹“ìZ¶›å]âlya8l&Óµ‰ ísÎ@:Í_J²ñöqK-¼É§^y·ì‹(b`tòÜgŽ& ȳy ý”@ñ•™¥28”¶•À{‘@³Ò´¨~Ò¶Övq[$æˆÖ5‰Xïç ½q“Ò¢Ohb[›ˆô}8IvŒ—-²feo¼ãæ¾zרëzÆk¯ FòénšÂþ{ÛIfë%Ja|ÍÊ»r$à’zÖ¤zž©mâ˜F¥wvš}Ì똷[v·bbÎÉ8óU÷9o€:Ö´¶iZV·ˆÈÑùLÅJtŸNO*µ®‡¤XÁ$zU¼RG妱¼W¨ÜÃqmeaw©EvÐËq²Æ;cò&ÐYÌøP °àN}«ž‡Ä:î±§I¨C©›!†muO*(#eißÎ'%”‡Ë€Aé‚9Èo©hú%ݲ>«§ióAh¥‘® FXTHÜ0 úS¡Ñ´a¨ V 6À^²ñv'˜Aûàg÷®+ÄÚ¦£©éÚò®¥ými ­ß’#F™R]ÛËvFÒIç ­í_R¹Òüa-¬©’µ¥¹¸u °,Žˆ\ƒÇ¸ÏÆx  OøG41qmqý§yöª©o'ÙSt*½e@튽=­½ÉŒÏR˜›|~bØØ+‘ž‡ Ã>„ú×'vú¤ZÝ–„i2ÝÇ•û¾ŸŸ¿@t>Ðmข MŠœyñ¥ª*˃‘¸†çÖ¤þÁÑ…Œ¶?Ù6d˜†–³'–äeÆ ÂÏ ô®$xĺ–«{%„A,î-ãéöQ#$nÆC#‰rC¶Ò¸½È«6Úž¶ÏܚĦ+vïMò1H–I‘;3½v/$@äÍvvúm… €[Y[B-Ñ£„G¯”ŒAe\*¹®¥W¹ðö‰y Ýhú|ñ[ÿ©Im‘–?÷A~Äh1k–ß ü3ý™¨^ÏæAÌ‘}˜N‘¾ä>b„8m¹ß“Œó]ƃ§ ØÞÃq-ÄsB¬%™;z–zãJuƇ¤ÝÝ-ÍΗe5€«,–èÎ93ÅZŽÚ¦šhá%˜ƒ+ªÒ07øsRÑ@÷‘w¨G¨\éV3^Ç—2[£H¸é†#"–ëBÒ/m¾Íw¥XÜAæ´ÞT¶èëæ1$¾ÆâI$õÉ5~ŠÏ—BÒ'¾†úm*ÆK¸NöèdŒ›XŒŒ{S®4]*òþû2Î{È0b¸–i#ÁÈÚÄdséW¨ Š( Š( ?ø%ÿ$‡Bÿ·ý(’ºJñøRåŠý¢X-]”àªK2Fç=°®y®à—ü’ þÞ?ô¢Jíu=: [K¹ÓîwyW”b§ ¹îb úŠåü_â‰ü4³5„¶Î–6Ÿi–ÈXO3”ºÉÛ!HÁ •w:Åâù§ ”OFäΔMuÚ—…4gÍ:ŒÌÓÛ‹{·D'AœT`›gŒUì 3íŸkû7ïþÒ.÷yþ´E䆯qþ¯åÇNøÏ4Éx†*ÚöH4é[QÒæÔ,቙d¹-óå[€\Ðækã»»ípÙÛClÖ÷W°Å§HC, ¿Ú çªù2c ®sÎz]7Âú6“pÓÙÚs‰CÌò,hNJF¬HIåPÒ›cá- Mm-¬ôõˆéqÉ™ÞÇÊY>øäóŸS“×ÔÐ|I©ßéòhðißeßß‹V{”fT_*W$Ã'1Ž3ÏN3‘‹mâMvû\¶Ña:tw ׉upÐ;!òL;Yx#"aXà÷8çkÄzöüšB>ß"Òûí31‘Šù2 ØËÈ`ΤŒc9ÍY±ðö—¦Ém%­±I-ÒT͉̎YZBÄ’X±E%›'޽h‹Åº˜k]Nxí‘w5’A7Ú#ØdËnÚÙ1¨Q€zœS$ñF¹iá;\­Œ‰¨ ²ZÁm+´&fP»ÙX™p$*)$`u®† hðjßÚqÚsæ<£39d`C:ÆNÅc“–“Ï&¢‹Â$6ÓÛ%¤Ÿf™v›v¹•¢A¸0òжØð@#` b€9óâŸ'Ûdߺ»½ùÑ®‚ùF2Ûűa!!†Ã† da;øªýot÷7VQéSà ÿ°M$WìC(u|Aü8ó3Ë{VÙð®˜mE¾ýKh3ö¥Ï™œcýg™»íœ{SO„4Cöuû4¢uEHêQ Ør»£ ±È<å  ¾-•`½ðÔÌ XõFb\ [ƒTôj¯&—6©›ZêÖ2^À–¨ÁàÚªû–"L«ýà‘Óšên¬-¯eµ–â-ïi7Ÿ ÜF×ÚÉž:ü®ÃŽjŽ™áGº766¦96ÓtÎë HÕ˜ˆÔ8PÒ€14_ë—zŽ‚/†öMbÊKÄXÃÀ• !ø“–téY1·¼—ÄÚµßüJ§‹OКâ(olZld.ÒÁpX˜ãm ÂXx’FK[K;{X%†mï&¸ÎöSÀ€¿q22ÝxÒ]èÚ}ô—R\[ï{«_±Ìw°ÝÍòðxûÍÈçž´ÂÏ£êz¤v‘(¸Ô5H"Wû,· 9>T;ð¸×$àWgá½NóUÒ|ûëg‚t•â;­ä€Hðê’|ÊÁÁéÈÉëDþÑî#$µaçL“³¤Î޲"Õ•ƒB@Ê‘ßÔÕë4ëU¶·2˜Á'3Lò¹'Õœ–?‰ /IÕ5øZ[³}·]»Ýs%Ê3„i"–g8 ®ÏAŽ8 ÒâÒá|=ö[;ˆ§×o^Oµéò]¤Hf™’Cáœ6TÓæ€=ŠòÓ.†´ç½Ógº»³kèí¬.ôI®`‘ íå “ Úª™ˆ z‘[°Z4<Šò=$Ü\Ü̦ss¦I¾Í|œßÜ(1Ic@W‹/®4Ïë—örywVº}ÄоÐvºÆÅNµ—ðÏJ±Ò~è)amâÊ©¶õ’WYRIü€`+¤¿±·Ôôë› ÈüË[¨ž“q‘ 29ô¯7ðljî<y‚¼k<C XÒ5–ÄP]@ƒžEžx’U¤õ *8'†êÞ+‹ycš PkÃcyW]ŠÛIá— gkn šÐøa£Ûé^Óf‰ç–ãS‰5+Éç”»Ë<ȬìIüáÎNIЋÁ>´ðõö‰§i°iö·Ö†Òw´VGB….A,À1å³É$ç&¹ÿ‡þ!}>+ox‰`²ñ†Þ$-²öÚ5&ˆÁÈ*~F$.P@¢Š§ªê¶:—q©êw1ÛYÛ¦ùe~Š?™$à9$€2Mpú+áïŒú΋`d¶˜5©¢’FaÏœcbƒ8Ëu9z%yÿƒ¡¼ñ'ŒµÝ[}–ÆKA¦èë’âÔH\ÎêÀ¼í+Óå' ðÇÐ(¢Š(¯?øµþ‘£ø{I—æ±Õ|Aee{O6ÅŠçªòŠr‚ ;@'‚ ì(9à†êÞ[{ˆ£š P¤‘È¡•ÔŒAà‚8Åxß‚|iÿ¤ðψõ+7[¼·²:e‡Ÿ‡ÈŒ¾àKXó“†×qâÏÙès®‹¦í?]nŠÓN·FI6nV˜n]‘ò¤’AÚIEÏxjo x|Á{qÖ©yq%î£s*²ÜHrÄ€…àvç$P‚|Dñž©¥xÒ/xr×Ä~¸¿ˆ%ÔZ•§”—/Úk3+á ùpå²;üz‹_¼‡J×4‰â¿“vÉtØ^t|cû¡ºEÀq¿<“´ Øñ«ÏøÓíÚæ±ö} Ò%ŠÎÒÏ&VÈ%Ù‹åQ·ãrªƒ‚3]LJ¼+¡xRÌÚèzdQ·ß( y0Iœå›Ž2N3Årà†oůñnTŠËÖ‹â½ËûCRÐ%–O°—ÇÚ •6J&@+øðÇ zMÄzGŠtµÔ´[èîí ”Þ ©VC+Tô8 pAèEjV_ˆô ø~óEÔ–Cit_Ëm¬¤ÊÀú†ó‘Ç Ž+R¹?øÍ|>‰¥éqÇâ‹Ôÿ‰v›ó!Üw aQFæ%Š‚¹$aü:ø‹£Þ|?Ñå×üG¥A©¬F)’âùC±™œ;nÜʪФç½uðø?þ†½ÿ0ÿñUá_…þÑÑ¿Ý8’OûéHOb»ø~ÏÀíáŸhZ.tßK9¼²²Œ0Ëç$œ» EÎr[©`4é6zeœvvZZÇÁ$“… ’OãV*½ýž§gå…Üv²gdÐH$FÁ á‡øUŠçü]á;?èík+ý–ú<=–¡5¤•ƒ#u^Qs‚ E‡^!¸ñWÃýX¼\]MIŽGÎèÍ?¸©lÆqÚ¬x»Å–~ÑÚêTûUô˜K->7k¹ *…Eêܺçpzÿ¼=qá_‡ú>xÙº†"ó ‘ÝšFN ib¹œg½uQEQEyÿ„¿ä¯|Eÿ¸gþ“µtú¯†ìµ­^Êòþ+{›{{yà6³À$G24Lž8ò½;öÇ<Ç„¿ä¯|Eÿ¸gþ“µnkWWóx–ÃI¶Ô›M…í'ºyÒ4f‘‘£PŸ8 (ÞIÀÏLÍ_m#@Ö!†áôí2ö!• †ä_/¦Õ8?/°â´µ¸çD&tXÚ@ƒs $…'¸›Üú×”èzÞ¦¾;°šziZWѨ‰n™Œ¤–Þ òÿv AËzWqâMKP‡ÂPÞYIö;Éç³,ü¿6x‘¯GøP·‡tK%‘mt}>•ÖIV¨¡Ù[r±À䆃،ՙ´ë„¹Iì­åK ¼JÂP웎9®:÷[ÕtØ5{©4¡gmüñGºçòÃ3UBT³`ãŒçæß¾£{¯XirëwOýŸ¯,1ßG"C¾ÊWÃ,¦õ$Ž ?#84ßãévö¯k›g»•-@ªŒT¤€0p@ôÚ=)·Z&“{}íÞ—eqw<©å·G‘1ÈÚÄd~™â{F4; ÷µkÍCìóL#Gc‘3œ”uÈ86¾·nöWWºÃ\@5‰ôÉb6ñªÉ@•\‰2€œ¸þô×Eáí.¤‹GÓã{µd¹e¶@fVûÁÎ>`{ƒÖ’ÓKЦºZ³°ÓžâT —ÐÂ…ÝHà‰É{ô®_Ã>!Ô.¼Mik%Æ¡qa¨iÒ^À÷ÑÛ!;^ ­ˆîÂCă<zã™ÐŸe'›¾ÎݼèDf0wÆ3„~C꼞:r}k„Ö!Õ-|G­Ïe­O Ö^·˜ÊÐÄÍ;¬—%C‚»Bœ… y"¢Ox›SÕ/%°‚è%œöè-“ì¢FHÝŒ†Gä‡m¥p8{šíçÐt{«¨.®4›n-ÀÍ%º3Æ@¤ŒŒ{Uadªª- “ÔÆ„’\q÷‰f$õäúÖ'‹/®í%Ð`µÔ>Â/u5¶šPˆÄ¡†VÚ7,«ƒŽ¸ê2Oöíëé­doï弬¶6óØCnf¹¥ÏúÁå)NÊN(£“Âþ–‚M Lxd”Ìñµ¤eZO[ß­iÅpD‘EÇ(TD @a^¢ëzÞ½6…lÚœ¶žjjBéãŠ$¦Þâ8ôtçnW“ŽÄ6÷ÄšÖ„š¼×òÝKv-®î,! Yȱœ©RƒÍT®àçžphÑh®k“k2Éuý¤÷²[˜¢x$¼¡ÙŽýû~ÎÄlÀLgžO'·K@Q@Q@Q@Q@ðKþI…ÿoúQ%zyÿÁ/ù$:ý¼éD•èQEQEQEQEQEQEQEQEQEQEQEQEçþ-ÿ’½ðëþâúNµ×IâTirëzj$€-夑6g<‚;W#âßù+ß¿î'ÿ¤ëL“A»ñ‰üUdoàƒM7ö<e/3‚$Þtîï@‡Ey®½$ž<Ó…¬ÒF—:•ͥͼº¬“Iµc˜ÖÅvB7F¥H`Hìrq”'6ðö­{¯ÜO%Ƙ'žÒë\žÖ[—*¤4L§æaÊìÀ ¸Ï4ì4W™x¯S¿:ëÅ%üz]³iñ=ƒÝê²X3ÜHTa+®(ÇÇvkFÐï|G{«ëw¶ÂÖæÞ5{{§X¡Ýmm¨~Rœýå=r0I4ØjZ¶›£[­Æ©¨ZXÀϱdº™bRØ'±8cQišþ­F•«X_˜°d·).ÌçÚN3ƒùVƒG#5â2ko§ü=Ò¾É4–·Ö^·º†GÕ$¶WmŒG— ©Wæ ÆÍ{=½õµÕÅݼ2n–ÒAë´ŒQ\zü®§Z±^måÄ^=Õ…äòÚh²jP–š+ºçì¶û#•‡*‡¶8fÂ’VÓu-Vos«ÚÚj :Ïm6«!sn … hcÙ€»8<ã%ŽH RªW:µ…œr¼×Qñ[Èî)$…U€É—N½˜œ×%à Ae¹»±7¿ÚSEo-ü¤—Êİå_ˆ\ã%ŒéXZíµŠj¾'·7óÁ¨ÜkkÃÛ_qžÐ"ÛNiÆ1À W¢¼ãT¸Ôô;ÄvZuÝÜÛ^ÚbIî¤y ‚A—îŽì1PIP7²!¤>(Ò×N[àÑÇÿ Å]|¢#y´8;°àsÜtàzµG=Ä6Ñù—G{•7HÁFæ!Td÷$€=IäúŽ·}vöÌׇH´“J†M9µ f[B&%Ã1`ö†O•Ï ƒƒ¸×[ãx¾ÑàhžúR¾]Í”³É¯¨Æ]²!@Ürzc<×Õ{{ëk«‹»xdÝ-¤‚)×i¢¸õù]Oµæ³j±­åѳ×.ßRKëhô‹T¾yæÔˆ²ÁK2¶eÝ!ÜW‘б%Ýå·ŽµÅši-ô–Ôcı9O2ëì¶þ\r° ¬g¶8fùI€=*Šñ«M[Voj7_ÛQ-úh—r_@5ye¹IÄY äQnÊÀŒ)žøº«•¸Ó®µ{u»›håÑRµ]ÎÒˆfÜêd‰Ú €1wtW%àN­:ýaß2ÛMƒ4Z”š„S€þêY9>…{∮Z×T{ Ù£ŠãÃw×{?µå»–G°¶à<‰öÊ£}02ì•\_[I´ñ'úRÂ'1í§£6·m¥Þ_\Mý†·QùÒ´ì& àº'Œ£ŒOð³i­ã»Ñ¥j³ê6ÃJ€ù²Ý5ÆÌ“ ;} \ñžƒ8 ÒÞúÚêâîÞ7Ki ŠuÚFÆ(®=~WSÇ­X¯+Õo!´ñ'ŠšßTº‡Z…©Óìã•gso#Ëç£d£åëZkγéºdš”‡Qÿ„’é&€ÌL‚%ÃFg;6yxÏÛŠíbÖ,f½ŠÍ%o´KçlF‰×w”Á$<Ž€²óß98¾¶:“iâOô¥„NcÚxBJƒžA¯1¼¿Õ<É.m%š[øañÛ·2:íºŒ(Ps  `*xÃûc^7‰%0ÿaG·Pžé®^O›ÌbO¡#?.xÅz}Ìxö+Í&ëÉ‘eXnŒfXõ9/ãìC”–Nqóc ]=çþ-ÿ’½ðëþâúNµèçþ-ÿ’½ðëþâúN´èQEQE^úÂÏS³’ÎþÒ »Y1¾ã#`‚2§ƒ‚ü*Åçÿð¤¾нÿ“·ür´4o…ž Ð5¿Ó´é0Qæ’I¶A ¢F`¬aÈõ®ÂŠ(¢Š*½íýž›j÷W÷pZÛ¦7K<sÀÉмWf-uÍ2 Ø×î'ÑçÕ¿³#»&çÌx†aqH –EŒÃ* #Ž g_xÎÑ´ÿ?Hf¸aum™%´« ¤—ÄÅ$ +à9ÁRFqÔP‡‡¼+¡xRÌÚèzdQ·ß( y0Iœå›Ž2N3ÅlU[FÓRId³˜MR´,êÒËÔѰxÈÈÈ#¨5j€ (¢€#žn­å·¸Š9 • IŠ]HÁ#ŒW}ðÀ:…ä—Sxr‘ñ‘²Bƒ(éØs×­wPÁ‡Ö×NžŒ¼nD—3:’yVr{Aï]¥…ž™g…¤–±çd0F#EÉ$áG$“øÕŠ(¢Š(®?Yøm¡jš‹êvr_hzœ™^è×ÚI”’Ì«eˆ$‘¸•ñ]…r~6ñ%ŸÃïßÚꑇµ·š×ε—sArFÅBS%\;'¡ã­pþðŒÞ/ðF™®Üxׯ¶óÜ£‰#Y%w#²2™•Î9Æq“Œ×¢xoÁz…¼ÉtëM×ÓdÜ_Ü1–æv8Ü^CÏÌT1 žp*OéM¡ø+DÓ%¶ŽÚ{{(’x“n]£Ìû¼[q$u$žs[”QEQEQEQEQEQQÏ<6¶òÜ\K0D…ä’F ¨ d’OÎj¾­©C£h×Ú¥ÂÈÐY[Éq"Æb¨¥ˆ gÔP™ÿÂ8–¾>Ô4?ê÷Þš;D¼»û:-ÝŠ¼ŽÙFøŠb2¸?p“±ÿ—Ä?ú)ÿù@·ÿ±ð¶Æàø]¼E©Ç_Ķ¡rŃaþåòDb=¥T“·qtÅrz€¬tQuÍBîïZñ§Q¾|˜Ã}å‰Ëd¶ØgºÊ( Š( Š( ?ð—ü•÷ ÿÒv®Ú÷M°ÔÑþÊÚé·"ÏÈúŒŽ q>ÿ’½ñþáŸúNÕ©­ZÍ?ÄO´z…Ͱ7‡lK ‡·$ÈzçœsòŒcœ€mË hÓ Q.“a ´ÿ`öÈ|Ÿ÷8ù »=¼71ˆç†9P2¾Ù0ܤ2œà€Aì@5ç7߈U ‘5 ÉEî·y§¢[El 1E$»@S!òÂ嘌gå-Í>MsÅFçNÒ&‹Q†yVêC-°²72¬nþP8|°\žŒà¿’ÂÎU¸Y- qr18hÁóF1†ãæãŽj±ðþŠt±¦"Àéàî¿fO+9Îvcü)š åÝÎgý¨"S0†ž$u<ç°¤Œv$vÍjPOko!€¼7ÛáÊå¶Ò¹_C‚G‰éƒO²@´·f3¨Ž$9%ÇxäóדV(  z“§ÏçÙivVÓa‡™ º#aˆ,2r}p)ÇGÓ QDtë?.(M¼kä.#€P p§Žœ »ETÓô­;H€Á¦ØZÙB[qŽÚIõÂÍ2mJ¸XÖ}2ÊQÆâ0öêÛ%'qq‘ÃIÏ\š½EFÖð½Äw m¸• é¶ -•²Çf(PD F„`ªŒp`zUª()|1 ,vÑ®‡¦¶bð(´19%F>Sžr+BæÖÞöÚKk¨"ž ׊T ¬=<RÑ@âÒ´è"h¡Óíc¡åÄ3„Àtnn:|ÇÖ£ŸAÑîn ºŸI±–âÜ ²[£<@t HÈǵhQ@ZÞ…¸úh¹òÞ K£;Ã,BE˜¤iŒ~ó=úcÔÏ¢i2iÑiÏ¥Ù5ŒDíšÝ hGL.0:š¿EU·Ó,- fÚÆÚqŽ%]Ø3ãÄ}HÔVº“cw5Õ¦—eos>|é¡·Dy2rw2yõ«ôP-?FÒôŸ7û7M³²óˆ2ýšyÁm g©ëëWh¢€ (¢€ (¢€ (¢€ (¢€<ÿà—ü’ þÞ?ô¢Jô ñÿÏñÁÞ±Ð?á]ý³ì¾gïÿ¶­ãݺF»Î1»{WAÿ oÄ?ú&ù_·ÿ ô +Ïÿá-ø‡ÿDÃÿ+öÿáGü%¿ÿè˜å~ßü(Ð(¯?ÿ„·âýü¯Ûÿ…ð–üCÿ¢aÿ•ûð @¢¼ÿþ߈ôL?ò¿oþÂ[ñþ‰‡þWíÿ€=ŠóÿøK~!ÿÑ0ÿÊý¿øQÿ oÄ?ú&ù_·ÿ ô +Ïÿá-ø‡ÿDÃÿ+öÿáGü%¿ÿè˜å~ßü(Ð(¯?ÿ„·âýü¯Ûÿ…ð–üCÿ¢aÿ•ûð @¢¼ÿþ߈ôL?ò¿oþÂ[ñþ‰‡þWíÿ€=ŠóÿøK~!ÿÑ0ÿÊý¿øQÿ oÄ?ú&ù_·ÿ ô +Ïÿá-ø‡ÿDÃÿ+öÿáGü%¿ÿè˜å~ßü(Ð(¯?ÿ„·âýü¯Ûÿ…ð–üCÿ¢aÿ•ûð @¢¼ÿþ߈ôL?ò¿oþÂ[ñþ‰‡þWíÿ€=ŠóÿøK~!ÿÑ0ÿÊý¿øQÿ oÄ?ú&ù_·ÿ <[ÿ%{á×ýÄÿôk´ºÕllí/®¦ºŒE`Œ÷ENã ¼î';H8ÆpG­yÜQxËÄü+«jÞþƱÒ~׿Ký§ Æï6£…Á€8¯lQ¬Eal>%#ÝȺ„¶“K³Þ?ϲŒÁƒ ØãŠôõ`Êt#"–¼Ç]“TÐ^òÓM¿¾–),í'¸iîŒ@ÎRWVÃÁN»W @®ÀóË=½û JÒöÏÎ_³ýŸR{ÿ+å”Ìê çœã$g  ®Šòý?XÆ¢ÝV[rЕŒ-ÄefÜK©$’.z|·Àñ$³GLþ\AØí‚ÛWÔáIÀì¥I\"²2xvçQ¹’ÖÎ O÷Ó­ÛÛ¬j`˜]YvüÛFsßÎpõ¹5Þ&¾²¿½qk¨Ú@€^ʱÃnÐÛ™XmÝŒ‡b[kmå€ÎMzeäÒêz”z\m­e6‹&¢«,°kÓJ°G䱨÷ž^ôS SžHÎÝÀì|-©4sªZÜ‹‹·†ÒXnšä8$”O4¨.@n#œrIæ€7ïµ -.ÔÝj–ö–êpe¸•c@~¤Oµ»·¾¶K›Kˆ® e%‰Ã«PG¹oÏk§xÏDÔõvHô¨­®#Iåâ(.Xǵ˜ž($¸ï\½Åí¼WÆúÞú{ßø‰15¼ J¢ÎO5ƒ.1‘F[¦T¶{ЫÑ^_y«jØÏozï¢6±,_nžþH7Z„b…®UYÕ<Ï”?pnç5cI[½SSÐì®u©'²’ BEm;S•ÖDY †˜g+½†î¾ç' ‘Eq?ÚW²|»Ôê_¶¦; €ÛdÞ±¶#£pGzÆ—]¶·[¯°j7Ú†œlàŽÚ„‰ä\4Ê£t¹& BôäÓè¯.µÔï®|%­[Ǩʂ vÎÖÞâÞýî"‘íK”3Þ8É9–]O¨ÙøžòÀj±YÍäK§-þ·:!!âŒ'ÜL€’ÄŽƒnÑ@©TŸV°G¶OµFÆæá­bØwƒ*‡,„Œàç8Á\u⸛.âšÏR:ü“MâK»FI.]¢ò<ÙÔ&ÂvàmR21ŒãŠÇ´°ÓÞöÃMQºKÑâ‹¿´Bº„†Xã+xÈv–%7/ñ ÎsžhÖè¯1¿Ô5+M q{)°ƒ[¸µ¹¹¹¿’Xy^áUFí«¿¯ÍT½Ô¦µÑ쮯ôè”QEQEQEQEQE¶ðÎc3C†'ó#. ìl¸g¡Á#>õ%^=>Ê„ÑZ[¤ª\‡XÀ`\‚üãøˆú3PÚèºU•ô×Öše½ÜùÏ ’I““¹€ÉäÍ^¢€ (¢€ +Ÿñ_‹,ü-goæ'Úu+éE¾Ÿ`Žî¦bPO ¹#,xîH›ƒÁÞ+ñ5¼WÞ+ñf¥¥Ü2M;Ãò‹hí‰2³üÆSžNîhÑ+å޶·š_Å J_´m‡U´‚]‘9£SkŽ3óûŽõéíÿð«?ê}ñÏþ?û áõß Kcñ+GÕ¾&ÞAªh‰Y[jB$‚9. <ˆ·1ÂŒ¸È ¸à½v ô_Ýy^%ñ¾³|÷Ëm07“HsóËVäàòŒgæÀOH¢Š(¢Š(¨à¸†êžÞhæ…ÆRHØ2°õu©(ÅZUÞ³ ½‹À—?h·™|ìýÜÉ!Î9\ÛZ[’Û$V"6. dcÓ(¢€ (¢€ ùsã}•÷†ðTpôßü'~ÿ¡¯CÿÁŒ?üUy?Ã6qyZωæ‚ÿù––ÖÒ -¦ŒglŽØùÕ¸`£Ýœ•©àÏ[xßK}NÃMÔ­lÃìŽ[ØÑÄgvͮĀF àg’:J( Š( ŠÇñŠ´/ Y‹­sS‚Ê6ûÉ/&j ³cpÎÆrx®_þoÃÏúòJãÿРQXþñV…â»3u¡êp^Æ¿|!!ãÉ nC†\í8ÈÆG±@á/ù+ßîÿ¤í]µæ™a¨˜MõµÑÄ‘yñ+ùl:2äp}Åq>ÿ’½ñþáŸúNÕèRm+N¸²–Êk Y-evy xT£³6æ%HÁ%‰$÷'5žÑ%ӣӤѴ÷±·%³Z¡‰O¨\`´¨  ðiöV®¯oio ¤Bhã V0r`}ÐON•bŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÃñmôz‡'šU”£Ie£¹6ûw:®æ”sŒüÌ: ÐåÇü?Ô'¼·Ö`–àO¦¡å@Ëx÷`!†'À™Ô3ÎØ${d€ d[Ë·Ô⿽šê_ÞZ¥ºvˆÄ$V=„íÀÚ¤dcÇÝišd:U´°@Ò2Éq5É.A;¥‘¤aÀeŽ=±Ö®×‘èsëz½Œ‘C­Äš¬ºdßk€jòÍp·;AVò (€«ñµH8çƒRèúþ«¬ëºd¢êñ-†úæÿÄ6Oq3¾Ý~ ŠX•@ÚQbv˜œäÕQsÆ·¢½Þ©rúÑ×å[‹¸fX£_8&"'»BÀ ÛºœÐ©ÑXš…Á×üy6‹u"½Í¬†Òx÷#ÁÚFp~ðZàô}UÖuÝ2Qux–ž"¹[»x÷°Cl_zE}°dwÞsÔЧÙ_[j¼¶²yˆ“I¤aãrŽ9ôe#ðâ³'›JÖ/t&7,ÁŸQ³O-“Ì ·\€ッ’= r:T2ØÍi¨Ã{xãÄ×¶ÒCç·’bi®2¾^vç 6ìnÏ|qTšÿVoøjþÉå¸Õ…ïeØ™äűÏ9,Ùç¾O­zµÃøê[BïÉÕ­.ì¼„Ý z¼—ò$¹9b]Ç‘Õ=W€9©-¯-$ñž¡³«ÏmÚ&eöÇ…$‡ËB Æå‹äØÆ8Åt­‡Šü/,qÌí§ê–l‚XÆÖ1È„dnãð­5Pˆª:Šñ»-Gìþ³KÍZóOx¼=k&¼íŸpU÷aAÄÏ‘Ør0zsšèuÍNK/ØM}|²ÊÑ[/öTœ–óÇ!™’ùg#!º4è”W˜èúŽ«qâ´[NÖ @j3,ösjÒo{pÎVÓËØÝŒq’Ü‘[^.¾´¶ñ^…§«\iúl–—1ŽííÑ™Lwº‘ŒnlŽN;à€v”Wë>$¾‹Ã^{ÜÜÁªZifê î59-LÃtž[, ¤NÅQK†|ær:[¶ÕøÛQ±¹½–þÉ‚Ø[‰ÜÇ6q1Û;Xå‰Ážƒ$俨帆‰%š8ÚgòâÀlÚ¾§ N`}+Ê’öò].ïìüMm$Ú|möMj[Ù¢‘®ãVbΊcܬANœtÔúÔVÖúìvú†£y•§ëQ76£2y %œ™Ì»Ã¿n õ#è:<¶±Úɤؽ¼ndHZÝ +’I`1€I$“îh+áóðˆå•‹Z©Ü½¸ö®–£··‚Ò‚Úá…8Ô*¨ôp*J(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+“ø…¯ßh^·‹IhÓVÕoaÓle•wG²Ÿ¾þÁCÃsŒ‚3]epà™|?¥k)“A¡kº¥Ôq)iɰt$Ür@O¹á?éÞÓš+Uóo®vÉ|åšK¹€ù¤bÌÇ“¹¶ç±ÇSž‚«Ø_[êzuµýœže­ÔI4/´ÈÀ8<Œ‚:ÕŠçüYá;źrÅt¾Uõ¶é,/²Éi1,ŠU”ðv¶Üà•è1Oáî¿}®ø~â-Y£}[J½›M¾–%Û²Ä~ú{*O ÎpÅt—÷Öúfsy'—kkÍ3í'j(%Ž'•ä~ ð$Þ%°Ô|Hþ!ñ>‹µ©Ü_ÚÚXÞ›oÜ»ü"m#y9‚»ph¨Õþ(é¾ñçü#:ý¤–L‘=ž¢eVŠE`A2 `:•ÉÏL£šî ž«x®-åŽh%@ñÉWR2#‚ç5òÇÄmmSƶÞðÖ§â]Ú!ûC^^¡o#0R£åÂîbq’ÚT×¥ü)ø]â_í»ÔüG=¤r|í¤Ú2É'a>apWwÊPìÀ“©þñST¹Uº»ÓücpУ¾Ó­‘½dýâ¶Dàqà· “¨ƒá÷ƒm­â<+£)’Ê7bÇ,À–>ä’{ÖÁ_Ýü-Óläù.­%¸‚æááN䣯UlpyäW P'©|4ð†£n¨š%¦Ÿû[¸–TÉ®z«`‚3ÁUꦓ¡Í¨éwöÅ·ïÅN×:Ù†Ctlí*Xå >Í©|<Ò/gñG‹´·$qii¨"U26Ò¨W€Ë†Ï}Ùï]«àK¸Ôõ?ˆÞ5¶³·MòÊúÇ ?N’H$Ðç„~'x[Æ›bÓo¼«ãŸô°#›øº ü)o”¶3йãÍá‰ì­ãºÕ/.#²Ó­¤%V[‰Ð2ÜÜddùcà üGãk‡ŸEÓd¶ÒÝØÇw&#UË`o „ÚJ/¨\×µø¯Ãú…g½·Ž×T³¸’ËQ¶Œ–X®#8`BÃpH±“‚k žxmm常–8`‰ É$ŒQ@É$žœ×ð—ý#Gñ­Ícªø‚ööÊ^žl%‚†ÇUå`€xé@„¿ä¯|Eÿ¸gþ“µzyÿ„¿ä¯|Eÿ¸gþ“µzQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQ^c«êÞN½âdMbñuxo­—K².ɆUcÎד¸`íæúîO.ÚÚ&šWÚNÔPKOô¯7M~á¼kdtùZâþêÖkYµY%s²9Šî·+²º5*CW±ÉÀ·v 5Ù?¶nnõ·Ð§mFÞ{Çv†_(ïq £Zôå`Êt#"™ Ä7(ÏÑʪí`À2’¬§ÁØŠæ¼!uq<—ɪÏ(ÖQ‡h\ˆ¢‹Ÿ,Ľ ü}IÈ8ÆÕå­dƒLðö³¦£uÒkR. «{$’ÛZµãf@…ŽÌÆs¼H%²HÍz|0ÅmpAE j#E ª `@U}ZÁÙ>Õ›†µ‹aÞ ª²3‚oœãq׊Ãðmи“WK;鯴ˆ®Ul®e§Ü j\,ŒIu O$žr3Çm¥†ž÷¶lzÒ^]ý¢Ô$2Ç[ÆC´±)¹ˆNsœó@·Ey-Þ¥¨[Í֢ɤAs}Ú/5yl÷:H¢%{…VbB–À$nÇ$㫼ºÔ!øIu. ³_ǤNâòÖCó0Šº¾ç€rç‘@}çvšÜçT›N¿Ô5M> Íxåä’;œ*–'Ë®ì¨ÆÝ àwÇU¼’fÆ×Tt·ó4–Š[MZ[Ó–ìÇ&ÙAåT¼Ï©×(¯+ºŸQ³ñ=å€Õb³š È—N[ýnt2BB1Ä%O¸™%‰Ý¢´uY.ã¼ñ>¤šúÉaªY¥´Krâ$S±uØÒ{dzä`ó@ü7Ü£<G*«´lQƒÊJ²œwGb*´Úd3k6š£4‚{X%´¬†2Ùã9ýÚãžçðä¼q£è¶Úר²\C©Ü‹ˆf¼’C½ËùDÆÌvî ¿6ìä“]ÕQEQEQEQEQEçþ-ÿ’½ðëþâúNµèçþ-ÿ’½ðëþâúN´èQEQEQEQEQEQEQEQEŸ©èZ>·åkiV7þN|¿µÛ¤»3Œãp8ÎOAZP?ÿ'ƒÿèTÐÿð]ÿ]PEPEPEPEPEPEPEPEPEóÃmo%ÅÄ©1)y$‘‚ª($“Àw  (¤ ƒÐŠZó÷ð©á«Ë«ïêX-̦iôkø÷Ø»)·ç‡-òç$(á@Åßÿ©ÿ&ëÐ( ?Oêž%¼µ¾ñö©úÛJ&ƒF°eŠ8rû¾y²0ß60KT‘^EOMÒ¬t‹v‚ÂÚ8ÜÉ!^ZW îÇ—s–bIîM\¢Šàõ jú'ˆ&ñ/‚¢Ïváõm*l$z†ÐØ(ø&9IcÏ I ÝèÿágÜAû«ÏxÉ.“å™môá4aÇ @À:ç8`9× Q@ÿ þ»¬¡ø{ÀºäWÏÿ-µ¸´*xÞÍ’_©(¿1±Òµ<àæÐÞãXÖ.cÔ|Q¨" í@F¨0ªŽ0Uç±=‚õ”PEP?‰ü1¥ø»C›HÕàómäåYxxœtt=˜dþdA òpø‡ÆžCmâmïÄ–ûÛÉÕtHU¥|±Ú²Ûü»HPIeùFTrrkÑ( ?ÿ…§ÿRŽðOÿÙÕ{/Ä¿åŽ-rËûÂ-óK¦Èê×—à2¼fBî•x!ê úECko½¼QÃH8ãPªŠpb«êZUޱn¶Ú´wVáØ%ù£rztp3¨\¢€ Žx!º·–Þâ(æ‚T)$r(eu#x Ž1RQ@wƒâÿ<ÇÃǯèlùF¿¸hçµP¡U ‰\?E@X’dÿ„·âýü¯Ûÿ…zçrh>/ñËÂ|O,z†¯™4k †’{¥*U’yÔ°õÂuW á€#Ð ‚­íâŽ"@‘Ç…TP0€ã%çþÿ’½ñþáŸúNÕèçþÿ’½ñþáŸúNÕèQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEU+=2ÝFê&½üë<¡ˆÀaF6ñÓ޹ç5vŠ*–™¦C¥[K #,—\’äºYFÆXãÛjíQEQEQEQEUMWN‡WÑïtˆu†òÞKy2u*HÈ#8>•nŠEPˆª:ŠZ( Š( Š( Š( Š( Š( Š( Š( ¼ÿÅ¿òW¾ÜOÿIÖ½¼ÿÅ¿òW¾ÜOÿIÖ€=Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( °|ml×~×àE‘ôé¬lC3ygcžN8ïÓ½oQ@{¨ëPøIÓ5½ömKOx¥³1‹Ç¹WÆèŽæfçÌ_/¯f;qŒn¦ÒfÖ¬%ñ¡>½gqgŸ ÞHEÄžD±pᘱ`A ~\æ½+QÒ"Õ.l¤¸¸œCi0œ[©Q®¸(_ß)3×8’ÏL†Æ÷Qº‰¤/:Ï(b0F‘¼tÄc®yÍyö«¨ê§Æ7ð>§kcsä+§¥Î­$áÚ„í·•›q. $xùp+Ó¨¢€ (¢€<äxß^¶ð•ž·y›#_éSÝÃ18K&P—;”…9ÆÒOZÛ“SñÔ,´˜¦ÒÖúâÚ[Ç™í¤1ÆŠcQQ ,ÛŸ—ÈwšÃþÒôïZØ_Û î?³¾ÃrVâV  Kå‚@@Äd• OS[šž¦ë¶C!h¤†y!u eÞŒ#88 {Fñ>¯ây"]5ll„Vp\Üý¦7›sÈ\lM¬¸Ë?9Îr8àÔZgŒµ=KX‹Ë²w°–ú[Ci×¢DgO4ÎG”Fäå@à7Þ$]ÞÑ¥kV[W€ÛB°Dmg’Ý/D>[ Ê?ºr9>µ$^Ó ÔÛP†9♤2²%Ô«sÕŒA¶=IÛœó@òx›]¤A¿Š+‡²ÓÎXÞm„eœ¶ÉA$(n+sÃ:œú¦Ÿ4—71Ïøçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+cÄ?|#á[Ág¬kpAtzŠòºp̨ \†nÆ{f±ÿávü<ÿ¡‡ÿ$®?øÝð«?ê}ñÏþ?û ?áVÔûãŸüöÜXßÙêvqÞX]Áwk&vM‚DlppA…X ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÇüKá«Ïj>¼³ñŠï>Õâ K9¡¾ÔÌ‘´lI`Tœíž0OìçÿÿæJÿ±®Çÿg¯@ Š( Š( Š( Š( Š( Š( Š( Š( Š( ¼ÿãoü’wþÝÿô¢:ô ñ‹?еOø«Ã^dözͬ±ÇöK¸Œm2¬ññžC)pçqP[æ€=¢Šäìþ#xsTñdÒ.dÔîÝåšÉ<È-ÕT6^Lã!A]ß1ÁÁ®²€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿâŸüÉ_ö5ØÿìõèçÿÿæJÿ±®Çÿg¯@ 6ñ_›ý¹›/¶kÿhý‹ÊýþÏõ>WæìÿQþÎ3ùÕó¤ß[ÜiZ-î”~Úe½¸ûr[ˆ¹Ýûç.Ü”R Î}{ª(DÓî­5¿\Oȯ/£šÜôС<>daÏ¥nQEQEQEQEQEQEQEQEQEQEQEQEQEÃøÇVÕ/üC§x/@›ì÷W±­JñdÙ%¥p…¢$æ9,ªFJ‘œ †^â¼ïRž#ãÆ›y¨K½¾§¡6Ÿg#°[…¸cö;YqœH'Šê2Ç,ÞÃ8+rŠ(ÌüKá¦ðÜøÓÁv‘ÂaEmSII+[›dV,Ê›p²¨Á0†,Cz%…õ¾§§[_ÙÉæZÝD“BûHÜŒSƒÈÈ#­s5['áμ÷÷1À.,¦µ‡wY%xÙUu$ŸÈN&µ<'cq¦x7C°¼ËºµÓíá™7µÖ5 288 ô  Š(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿâŸüÉ_ö5ØÿìõèçÿÿæJÿ±®Çÿg¯@ Š( Š( Š( Š( Š( Š+ûÅžÓ/$³¿ñ•iu7Ã=ìqºä2¤ädØ¢¹ÿøNüÿC^‡ÿƒøª?á;ðý zþ aÿ⨠¢¹ÿøNüÿC^‡ÿƒøª?á;ðý zþ aÿ⨠¢¹ÿøNüÿC^‡ÿƒøª?á;ðý zþ aÿ⨠¯ŸÿhŸÿǧ‹ì¡ôµ¿Ø¿÷îC…ú¡f?óÌ öøNüÿC^‡ÿƒøªÏ×Õ©%î½m.Ÿâ-#OµÈ·¿’Rή¬ )8Êç¯l`ƒRÇá}"=:êÇìÎðÝ8’v–âI$vÚÆFbùW<`c{®K/‹-ôùmmdŽßWŽ”—MÖrHXãvr3Ž„ñÞ¹{-SU¸øjÚ~ž,ÒÞÇÃ1Mpn™æó"•` ÜCdœ`c5è¾Ñìç[9˜\‹¯2K‰$c(ŒÆ–bIØÄsýC7‚ô 좳{'ñÚ‹=‰s*„gøa¼ œnÏSêhSKÿE—ýpOýW,<]v¾(¶±ŽK{Û;»©­Sɱž?-Ñ$p<ö&9îʸ úàÖäÏ®ÚËäiú^™%œaV'›Q’7 ÕD-ûèÓÂZ*ÞGt-dó"šIâi”¤nვMÛW!Û8“ž´È^x^¾ðô‹%ý½†ª—Ví³ç‚HÜ¢²’Ò~õ2pYpÅÆ÷ŽcÔ¥‹íVÞ{ÉS¿ÙÛdŠÒ¢° ¿ ò 2;ä__è‹Ì-oq(¸TGyï&–@ªÛ”+³–@‘´ŒkB]&ÎãLM:t’keØ@–gv%2’äî' “ÏzæW\ºÑô}b­ìû"úÖÆ‚E^;rÇfãŽf|xuÁ%oüI¬Û_ëRƶÙú]õµ±¢s,«"BÌwn‘æ’>Sœcާfûº6¥w%ÍÕ«¼’&ñŒ×67+¦\jYÉ‘E$qbk•…•”¹9È`yÏAŒíQ¾¹¾Õtý@ÛÉ=ŒÈ¢kxÚ5‘^5qò–bÉNp)-ü%¢ÛA$Ik#‰fšæY\˜œ£wyuwd²Oyfl'}ì ÀI;xÄpäŸj½qâ½pXXê`YZé—q½ÇÚ–Î[Õ·A·bIå8Á ³û«ŒsǪ“AÓ%!í².n!¹›÷óIÏ-ºñ)8sœœÓ¸ðn‰rÓ‚æ4ÙåŠ Ù¢Ë}ì¢8RR1‚I'’hr'Y"I•Õ”Êr=ǵ:šˆ‘F±Æ¡Q@UUÂ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ñOþd¯ûìözô óÿŠó%Ø×cÿ³× PEPEPEPEPEPEPEPEPEË_øÎÑ´Ö¸Ò®\ÛD$’ÚU…ÒKˆâb’ðà©#8ê(©¢²î|p›É\à€9=;j+”Ó|q§ÿÂ=¤Þêóˆnîìc»™ ‚GH•‡.ÛCyiœüÌ@àóÁ®¨ÀAE-Q@W?â¿é~³·–ÿÏžâêQ ­•¢y“Ü9 a#8ÈÏ=Àê@ ×özeœ——÷pZZÇóO $–< ’ã^g%æ¥ñqá]2Ò; Ú^ï]V}Âêé‘HY-@ÄUó‡'®2FnXø;Yñäz·ÄÝÛÁvf±ðì.  ÎÀ~ù^¸örƒÒ(Îà—âG„íâÓÿ³-Ö/õȵÿjp_]Aµ­4Ë5u±´‘w(V9’L†a•,qœ)^âŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Ïþ)ÿÌ•ÿc]þÏ^^ñOþd¯ûìözô (¢Š(¢Š(¢Š(¢Š(¢Š+Ëô] GÖþ/|@þÖÒ¬oüŸìï/ívé.ÌÛœãp8ÎOA^¡^á/ù+ßîÿ¤í@ü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ÿü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ÿü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ÿü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ÿü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ÿü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ÿü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ÿü žÿ¡SCÿÁt?üMð‚x?þ…MÿÐÿñ5ÐQ@ðKþI…ÿoúQ%C¬I«K¥üI[‹ø¥±† ’8 /¹3e ¬\€>c‘·’Iã8©¾ É!пíãÿJ$®ªëÃZUä÷óM¤ê.‘ndT™ ì9@Áwmãv7Þ€9‹ÿë:šÖú9îWµ6ÐJDfY|¢® ³>ÞTÝ0+{ýþ¦—‘ßÀá­ä ÇØf´YÔ¨9ËóAäŽÏ8o4 /PyZîÑe2À¶í–o¸­¹qÏ7 ŽAÇÓw ÷˲DKm,¨!Z9˜sœàŽ•ÅG'ˆ'þÈwÔ-.%ÿ„¢ò( °Iû½«x¤“æÊùPmÀg½z—£Xèé0³IwLáå’iÞi€ÜîKÉâ«Çá&@^¤‰…É»Qö™ k)WVqí ‘#çœäó@íÇŒµ+}2ÖŠí9u)ô÷šI§| ìd¡.rª>]ÜrØÐøsT»Ôôƒq¨[µ¼ÑÊñ±x$€Hªx$Ÿ2‚0pzr2qš|þÒ®md¶’Ù¶=Ë]îI]f9Ë«‚O'î‘ÔŠ·g§ÛØY‹HD­9óæy™³×,ä±üMqv¾3Õ¦¹¸¶¶ŽßT’]6kÛ&†Æ{dvŒ ØBD ùŠC!: ŠŠ}kYÔdÐÒ×Y´K¯ísêtÉíöƒm+…’”1g®ÊGÝ祃Áº³+Em8d·kXɼ˜˜âb¤¢ÿ(Ê.1ŒcŒS¿áÑ~ÊÖæ“ºapg7³üÀ»CyÛüÌ…$}ô¶ íˆ-ŽH®ÇA‚?ˆ–bÿZkk[ K¨¢“Xºu4³†$àDh0r8éÉ®ÂÞÆÞÖâyâWO´ÈZFlí]£‚N8ºõ<К}ªjsjK.æ… y7Q 2Œgnqž~”溊5O xDžöK‹&К{x FYU¢ †bH`ÀöQ·ý®µÖxk\Õ5 Bâ×P™•.WM¸´MÄÑânXŽ`yð1Î’xoHKK+O±#[Ù[µ¬»3*ÄÊ”‚~`@œÔš^‡c£—û'Ú¾`ÝË0P:3mÃÀêÞGâ_j“.“t¶÷Ö6ê·,Ò,NЩ'š6à¶î„ÇjèæÖ|A%÷‰ŒsE¥0ŽÞßËc-ÛtÛÀgô9py;sèZmÁ»2Ûn7rÅ4ÿ; ï݇¯ؽ:ãš{hö,·ãÊeþÐp÷%%u.Á©ÚŠ>\tÏZâ§ÖµFM -u›Dºþ×0N§Lžßh6Ò¸Y!yCÆzàü¤}ÞzoêZ•ƒèÖöeóïï¾Êï›nؾÖw['všÜ©‚÷™v¼óáLj¯¼Iá+Á6úõ§†í,¾]íè’GuŽØ`m;¾RrO+ÔeXÕõÿÜͪ7‡¼i¯®%À†îYþÉ§Ž¤Í ÀΪs•a÷€V¹áO‡ö~¼¸Õõ+í¯]Je›U¹„ óå¨SŒ)ç§@ª74iÒ×MÑlc´´_b’Řõ,ÌIcÐd“À ©@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ñOþd¯ûìözô óÿŠó%Ø×cÿ³× PEPEPEPEPEP^á/ù+ßîÿ¤í^^á/ù+ßîÿ¤í@EPEPEPEPEPEPEPEPŸüÿ’C¡ÛÇþ”IVnu«ûoÝÙi¶öMs­ÅfóK6å6"Rì °Úè0ëÍVø%ÿ$‡Bÿ·ý(’ºó¡i­öÓmþ‘ö¡w¿{­y!±œ«ùqÓ¾3ÍVÐõyï4›¹¯Ö?>Êâx%0) þ[¹T’F@8=Íaø_Åú¦µue%Õ¡W¶Íp4ûˆE¯•ZYÉAüË·‘À æºëKk™m£Ø&™ç“æ'.Ç,yõ=ªŽŸá­/K™¤³†hÔ©Q ¹•¡@z…‰˜¢÷@ H|A¹´7rOäjãLžþÞH,gµFòÊ ¡ä%dSæ)Þ¼ r9o]ÄKqá¡su¥ÉxÚ°òš+i8ókq»p2øê0W>ÝkrÛÁú£†ŽÉŸm³ÙªÏq$ª°>ÝÑ…v /ʼcT–žÒ¬¹Š;†6Ó ¡ó¯&—Ë`Œƒnö8]†Þœôé@†õ+­OO˜ß,"êÚêkYZ*ŽQÈ  ’FF 8õ5ÆøKP»¶ðüCOÓ¡¹½ƒÂöSCÁ36œãh+89cϹë@~×oõVšVH"¾H’G±2ÛÉsK±®F®¦³ÔµmS]¿KW²ƒNÓî…¬‰,.óLv#± 8*ÙÆxÍ^ÓŠÖ?-i'a¸œ¼Ž]Ï>¬Äþ™Âƒ“ØiÞ3ñ§b.mtå™®¬îΛsBáC$m+áeÜ —o `k°›ÃÚ]ÄòÏ%®f’å.ÚA#ª*¯Ê¡Hdäæ_ÙhþlúM»‰„l!·’öan¤ó…BYcî©Ç§jÅ“Æs\%Σ¦­¼šE±±JêK7œÊÒAÀÙ‘·Ôš­¢xæ÷S¿ŠÞ[ku $÷?"±-b±+Ä㟼L±‚zpØŒlh~´°ð„ºì0Éߜ׉`Œe$²©àà´t­OéV:‚_ÛY¬w)h–Já¡Ê¦3Ž~½9â€9|g®Yhi©ÝE§:ßhוœq#þᣌH©!-ûÀC °ÙÈÆ9Ík¾¥â#¨ØéQË¥‹Éí¤¼’W·Æˆ¥F™–bÎ~|€û¼Õȼ CÌ)bÞUͻڲ4ò2¤/÷£ŒÄj}oAè*ö¡¢Xjm\Å&ø,rE3Äê­Ë¹%NA88”ÁxgĆ‹áø%6ö:kÚ@~Ñ-œ³¤®ÎÁ“ÍF >P ‚ o½6°SÁšqÚ–³-½²¢Çn.æòp‡+º=û[ûÀô­7L·Òã¸H7Ÿ´\Is#9É.ìXþ€=€ëÖ€9¨¼[sÿ e¥€žÞîÆòîkEhl'ÉdIý{‡÷l¥W\͇Ç:ÕŸ‡´ýcR‚Âd¿Ò¥½Ž dxÌr"£,ÌÙVÝè6ÿµÖº¸¼)£C¨C{´‚h'{ˆA¸¤r8`ì¨[jç{dŽsÖ¤ÑÅ•™²V¶³¶kXcvfU‰”+)ÉùP9  Mj‹ñí5ilåœi0ö‘´kƒ,œmfcÁÏ9çÐSuŸÜéšúC ö÷‹yoi4 a;4fVEË\å+ ;Éç$Vö›áÝ3I¼’îÒ)¾Ó$K Ë5Ì“1E$ªåØð ?EuáMòñî§¶‘¤yã¹e,fXÊ•r¶îœdã4Éë^$ÖÛGñ-¼÷0é·qXÞIkئI6Æ$I÷ìíÁù@*Xg¦u¦-âéЋûˆg¸Û–’LjGo”³Ö¨/…4q<Ó=¼Ó´ÑÉ-ÅÔ³*¤Ÿ}Q]ˆ@{í´4û4Ë4´¶3˜“îùÓ¼Ì?àNKcñâ€-QEQEQEQEQEQEQEQEQEQEQEQEçÿÿæJÿ±®Çÿg¯@¯?ø§ÿ2Wýv?û=zQEQEQEQEQEQEQEQEQEQEæ÷w> øƒ®jÚN‘ªÿbøsK»[[‹ûMÂòætÃKG”£ ÁÉ•˜H¯?ø%ÿ$‡Bÿ·ý(’€$‡àçÑÌ×:L—×nŒ&¹»º–G™™Hgo›ÎIÈä`Šó|"Ó4ôø;TÔ¼1x\½­Ä’Å1Vy±;à À óäq^‰YúßöÇö<ÿØaþÓù|Ÿ·ïò~ðÝ»gÍ÷wcñ@7kàFøŸâÍ}¼w¨Éµ¤<6‹g¤…H£€©tpî¬X9f ™psŒ€;K‚ž±û3aý¢h62ââGóqË®í‡$r6í=1Ž+ÿ‹ÿ “þeOí¿øGÿéãìßgûGýõæoü1ï]‡ü]ÿú‘¿òn€;È †ÖÞ+{x£†$qÆ¡U à8ÅWÕo&Óô»‹È-$»xÌ6ñg|Š9`€¹öçjñ¸àdg#‹ÿ‹¿ÿR7þMÑÿþ¤oü›  MâO…ü€rÅíõ¶n..äòâ2Gm¤üÎáqêÌã\?„¿ä¯|Eÿ¸gþ“µk|EeOÊÍ,‘(¼²&H†]Ú¢åG¨í@Õýµœ¶±\I±îæò!IÞûYñÇO•äñÅX¯3¶ºŽéÑé÷ó_èñkqýšâK†¸Íǘ«#X´õ8,GlÓT»:½¯‘©]Mâ'Ôîc»Ó^áŒin<Ý™‹;QˆŠ¸±#“œP¢^ß[iÖââîO.#$qÚOÌîG¬À~5b¼ž[Ë{ŸÇ5®­-÷ˆÚ]=ï-nï\ùsý®‡‹$Bñò¨ãÖ»\ý§J‘®.®eÔ„¤_ÇppÐM” ’@ÆÜpF[$‚Šó[=qæñîœ-g’$¹Ôn­nmåÕdšM©Ì7[ÙÝ•!#±ÉÇ¥PEPEPEPEPEPEPEPEPEPEPEPEPŸüSÿ™+þÆ»ýž½¼ÿâŸüÉ_ö5ØÿìõÍü]Ð>%ê–óQŽçEØÞe…‚˜'+‰2,L£i @o˜‘ˆøÍwÿ¼9gâ[?Ás&¡«\Ü µ‚y¦X3HA„Úw îœcšë+ä…[°ø‹öM. *-oÊšãÖ¡—ºòàl’@ªãœq¸u ÿ‹¿ÿR7þMРQ^ÿþ¤oü›£þ.ÿýHßù7@Eyÿü]ÿú‘¿ònø»ÿõ#äÝzçÿñwÿêFÿɺ?âïÿÔÿ“tèWŸÿÅßÿ©ÿ&èÿ‹¿ÿR7þMРWŸøKþJ÷Ä_û†é;Qÿþ¤oü›¬ÿ†ÿÛð±ü}ý¿öí?ø—yß`ßäÿ©}»wüßwnsß4êQEQE@ë!­ÃJÊn.žÒ Ñ8Ý*‡,91œô8àœŒóZÅå ñ”¶úî¯>f¶°¶ž©xöÉ<…ŸÌåHób1°çƒÓš§ Ä×/¡<óI+/Šï£RìX…QxF{°Ü^ß[iÖââîO.#$qÚOÌîG¬À~5b¹_ˆ¬©àÙY¥’%–DÉË ûT\¨õ«žƒXKMb ¬õ™æðÔ´j×’Þ4±Ö³‡C+¹†¤€ÍŽØ‹=ÔVò@’ <žT{P¶[inp8SÉÀíÔŠ¯±a6†ºÔsçOk´‰¶0ýÞÝÛ¶ã=;c5ÆéúÅÅáÒ¦Šúy!ŸÄ×P†óŽàªû§Ê¤œé\ªÜÇÿ(‡RÕ.l£Âð¶›W Ï!ŽO3å·6œàÇ9 gŠTž–3¹C)Æ2"ŸT´æÙ¢Z> m·C…'å+Ì4ýv{»¹£³ÕÍ…½ö‹s;I6«%ë[J­V: #Ub¶@=b{ˆm£ó.&Ž(÷*n‘‚ÌB¨ÉîIz’*Jò»‹›MOÀº‚f0Yjvm-ÜÄ×p²‰¢.é;ØUÉ#¢‘ž£5é¶Fݬ-šÒo>ØÄ¦)|Ó.ôÀÃo$–ÈÁÜIÏ\ÐôQEyÿÁ/ù$:ý¼éD•zÿĚ͵þµ,kaýŸ¥ß[[Ú'2ʲ$,Çvì)i#å9Æ8êhüÿ’C¡ÛÇþ”I]|Ú›p—É-¶å¾™'¸Øotªzñp08÷4ÏZx£UšæÆöXìÿ²¯µtøáTa<{LŠ®_vÖÉŒåBŒÔâ³/õOP—DÕ'‹¥ÿmÉP¢7ž¢%w3ÃØNУžk®‡Ã=¾­ý§©>cʹ™Ìi#Ö2ÛŽNXNO<šoü"º7öŒwße:;ƒuóäòÒRçîÚ ÜÙ s“ž´Ëiž5ñ£d·VúIºûU„—Vð¦Ÿq…†Didù%Ü ]¼Ž2k¦ðέ.«iqö›¸g¸†]’"XËhÑeA ÑÈÌÀóœçt¥ƒÂZ=ªÊEsR!O)ofÆ_-7íþ*æ—£Xèé0³IwLáå’iÞi€ÜîKÉâ€9ȼ[sÿ e¥€žÞîÆòîkEhl'ÉdIý{‡÷l¥W\¡Œ5Åð΃r,þÕ­ì1 { æ[uòšFbˆÅä$(Àq“’@ÍuxSF‡P†ö;iÐN÷ƒq!HäpÁÙP¶ÕÎöÈç­HþҤѭ4“lËgf[•ÕáÚ0¥dx qsÉõ tbêûB’óQµ’¡y³o$>j©8uI>e 0pzŒžµˆÞ ñ"xJ :S}¸ÚkQ ŸºÍ€òoùþY:…^{]mŒuªÛ[ù¦0IÌÓ<¬Ië–rXþ&³!ðŽ‹oE´Âé"Àn¥1FRE‘v!m¨*œ(Œtâ€9Æñ†¹«wj°-ذ»KYRßI¹&ã!™dRÉպų·$¨"®ë>-¹Ó5ô†íî-òÞÒhÂvh̬‹–¸ÊV@v’1ÎH­Ûi—:™Ô9Ò労†©bYJýÒèŒð0< Tw^ѯ/ê{iGž;–Qq"ÆeŒ©W(ná±yÆN0s@u¯ˆõÝ.À$×q]Ë{­^ÚÂÿ`žsÇ,ʼnDvg@Ý£©À­ˆ|K¬ÝXé–ék¶¥{{-¨šêÒXãÙ;ù¢&*ÿ2¨Â’0Iäãy|%£Ln [Î<ù¾ÐBÝÊ¡%É%ã¿vÇqÉL“žµ3øwM“O†ÊD¸xá—ÎŽFº”ÊÏÌ%Ý¿8$gwBGJÉðdÓE¢j³^3G©Þ|œ•$HÙÛž{tªÉâ|xnÏY“û0ÿjd³·Xœy ;¨S$›ÎðdáW$`uÍtú^“c£Z5­„&(ZF•vr]ŽX’Ä’I9¬øü¡Çm=ªÚËöY†Ónn¥1 Üyh[lx`Ø  YœñƒÐÁá=Úö ¸í¥ómæyá s+$r8`̨[hÎöÎ$ç­Y³Ð´Û°}šÛËþÏ·k[o—lÊòyÿVœœž=Íq#Å÷ÒFÚ•­…ŠßÍa¦Î‚Ó]É ) ýÑóã “œô­iüKªÙC¨ÙʶSj0_[YÁ2ÆÑÂÞ~ͬÈX‘·qÈ ÎLñ°žÑ#ŒF–XP kô†S,c¯g$ûô9R꺭Ֆ¤"±‚yïv4‰<ÏÈɧrä¡eÖ€ ðþ§©Ýê:͆¦mM>hãImcd_%Y›æé“ø×ž Ÿû!ßP´¸—þ‹È 2Á'îö­â’O˜w(åA·žõ×xOÃóh‰¨Ír"Iï®­wNTË #|¤– uÇj¹†t˜uzJ&&íGÚd1¬¥]YÄ{¶‚Dœs“Ís·2Ô­ôËX^(´åÔ§ÓÞhm&ž5òƒ±B„¹Ê¨ùwpIË`Vöƒ¬]_hRÞj6²C4"¶mä‡ÍU'©'Ì¡†C‘“Ö¦ŸÃšUͬ–Ò[6ǹk½É+£¬Ç9upC)äýÒ:‘W,l`Ó­VÚßÍ1‚Nf™åbO\³’Çñ4À gT—Sðþ·ªM¦AúUÝä%UÀ·"`²ÇxŒ°ÛÐñÒ£ÔÐxănY98$®ÑÛ'¡ÿ„7BÑA¬±¥’d’©c•ZC—>b°˜òFpjÍdžô«»ˆçš Òßì§’,²E ‰Ìßx¦€2õïÞirkkvíöµ·©9yœ6ù~AÓ¯5‘âßÙßÜX¬vÓ\ÛZÇtË•u8”¾í°ƒmŸpþñºîN t‘x?DŠ+ÈþË,‚ò×ìs™®¥‘žFÍÌÄó7CÆj}CÚf¥p—Ç:N‘ù^m½Ô°3&sµŒl¥—$ðr9>´mâ=JOGk|±éÖ“:­´72–œƒq8o-_vá°®~S]udÿÂ7¥ÿiǨ4S¼ñ¿˜Š÷R´HøÛ¸F[`lw5­@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ñOþd¯ûìözô óÿŠó%Ø×cÿ³× PEPEPEPEPE…aãR…f·¿Ä/n×),ÐÉSœkÑ( OÁ^Ô´wÕµm~âÒã^Õî·RZ$h»bAêsÉØ%±“ÖQEOUÓaÖ4»:å¤÷)åÌ€^3÷“8à2åI ‚¹EcÚøWB±ðôúž™¾™µ6–!Š7…üF¦,ùCä?3nëÐàÕˆ|Kª7ˆ…µÜqØ[J@µ·¸²—uÎb q»ËVݸl+Ÿ”Ð_EqzF¥«øŠÒK;»èìu(ÞÚâKT²šÚHTJг9óU‚²o\)ç×¶4«ñà÷ÒN¥!ÔÍàÛ›p©Lç9ç®x  š+‹Ö ŸJ—Ãíyt÷Dk“N’J¡·¹`ƒ'°â©¿õ};I¶Õ5{¡Ô4Éoía· UV»!Á2à.ès@EqÂ^ë3h7—–1É·ÂæÊ9"$}£çŒ‚ìpV2½yÝÏ¥tšE¥Å†‘ikwt×WFIØ’d#¹Ï4vŠómkÃúÄ6›y«ÁÕý¼R­ôp²Üƒ¹KŒ‚ñ—#¹ ö9©ý´Ú-ÌzœÖ–Í&Ÿo­îŽÎ&‰%hç„gif+¸ŒžOZõJ+Œ°ÔµÍzÛVÒf2A,¶'ìú„ZuÍšÅ#]¸—’Tí`ÊF}+¥Ò¬îl­æŽêé®]î%•Y‰;Q˜•^{@ü(õÄù~ ðÔ:U’êQ_\êpÚ¯’ÂZ1vp$–ˆ¶3ÎãÜæ¡ŸÆ:ÄzÅÕ´¿iŽÂæ+Y£‹K¹v¸%PÈë"å"~B¶âvòFA òŠâ[ÆSÁâX-šh/4û‹‰íÁ‚Âtòš8äõìLrÝ2•\}pk-å×¼C}¡Ë=Í¥«êšEì–j^ÔÉ{rÛŽò7)Ü»yŽ”kâŸüÉ_ö5Øÿìõèæ>>³¹²·ð„wWMrïã+YU˜“µ¤*¼öøW§P>«á] [ÔlµGL‚këcšÞçdFBYFá‚TNÓ•ÏjØ¢Š(¢Š(¢Š(¢Š(¢Š+Ïü%ÿ%{â/ýÃ?ô«Ð+Ïü%ÿ%{â/ýÃ?ô¨Ð(¢Š(¢Š*9ãi­ä&xÔ¨–0¥úÀŒpGµIEgiúmÝœí$úÝýú•Ú#¹Hƒ‘ÈòâSžÝqÏJÑ¢Š(¢ŠÊMè¾ûGü$Z™‹Ìßöc·—Œçf|Û{}ìã¾y­Z( Š( Š( ?ø%ÿ$‡Bÿ·ý(’·!Õõ[ÝWS{v³‡LÒî<‰c’’iˆ]аpï€ œgŒÖÁ/ù$:ý¼éD•ÖIáý6M_ûSÊ™.ÉVsÌ‘¤¥Fº+rX‚€1t/j×Wz7ö’X›}jÍ®íÖÙX=¾0G%ˆ•þð ÈéÍgèÞ"ñN«ÿîé4x¿µôé/[²7ÊÀ½³æôã§ôúg†4èÜØÚ´rl1¦éÖ$$‘«1© p ¥Mg¡i¶Ùÿf¶ÙýŸlÖ¶¿;.&Ù•äóþ­99<{šåtÿ꺆¨† –ÊKÉ­D+§ÜQD¦à(‚È2 p© Љ|c­G¡ÜÍ;Y.®’Z/Ø&±šÜÁçN±¶âÎ|ň˜…u+á*;ù/#Šxä‘ÚGŽ;©V&vûÌb ³qÉÉÛœóÖ²µ_X\i3ZÙÆÍ,óZ™^öêiɆ)ÒF@ÎX€Ø'·Z­7‰u¨µ±áÀtöÔä¸DKÏ!Ä+Dòcß’ÃËaü䎔áâmbk=6c±MBmb].áÙ¢ZJÆDPÀóå©ÚOr3ÞµÿáÑ>ÆöÆÚbqpfk©Lþ`C ‹y€…àa¸t«Ph]µ½ŒÚ…ŽÆf¸·Ø•‘•Õ˜œå‰>Kg%³×šç,üI®jWñéÃNŠú&º7Âí¬2*ˆ[x',vàýêÂðæ·6™áK»¸m-~Óeáx¯Ø,Á®HF Œ )Ûæny㺛ÂúDͼÛH’y²MæEq$oºLù•ÚØ\ãÇؼ'¡Áa5ŒV!-¦²{Æ$|q¿ ×õÈçž¼ ýñF·¦\µ…ÂiòÞ\%©µtÒ8Úi¼¢%‚ðr6îéÖµü?©êwz޳a©›G“Oš8Ò[XÙ£WÉVfÁùºdþ56³ Zê×.,`¸º’€,óQž”Û h÷#-o,r ¤œḴH¯'/‡F ÀÈ8  ­rúãSøK¬^]ZIiq.rÒÁ"²”o)²0Àg¦@8ªã;ÅðÄÚÔ6Ñys•œ7yUÌ‚6yU2zœù`nãËazÙt«9ôit™ci,¥­äF‘‰d`T‚ÙÝ’ ç9÷ªóxsI¸7žmš°½T ½€rŸu°Œ˜|Üxç¬üWª£Âu e‚ý-e»k í¤‰û·T”åq.Ô<°ùtªÓøÛTN´¼ö›uX'm4272y¨¶ÁþnC£†8ÇCŠÕ×<)ö¯ Ýhzx-û¸šúöiž4îè_yf\¨Ï9ãbëBÓ/SNK‹DuÓ¦IíH:‚ªF8¡ãò BÇÆú®±=¥­Œ6PËtðÛù“FΰMövžpT0ݱB‚9$“V­Î+Kee†!„ ìä«OâhÏ"’òßÁO‹×X¾›S¹6“K\±‚_9Ð4"ìP$ó[~$Ö^êÞ{•°ûÚÍÆ˜"Ž'…G•VMňÎc®ÞùÈéZÐxCC·¿KȬˆxå3GžC råÖ"Û¹'!Aæ­®…¦¤qF¶ØX®Þõöâgffn½Ë±ÇNzt ?Ãþ"ÿ„{ÁÞ{ÑérhÅÚLë,q õÆ ,‡§T÷­ëÍgU±ð…Ôööˬ]½¼2ÊŠYYTäg$.ãß'³QkŠûNÑ´;k[dÑì§ŠGó%bè±QwnÆÒK õÏ÷öº”–—‘y> \• ‚ ŒA‚9(‚Þ£áù¼Ssr–÷7çP³¶F‚<¶2G†òÁgà6v‚IÆæ®Ûø«\¸’ 5mâKÛ›Ï" Û>{hZ1 JÏäÈC’6•Úƒ‘Òº¼+£Ei{möFxïd¹2Í$#(X³1l«‚F¥#xWI{±Éԩ扖Io§yQÀÀe•œº28#©õ  t¹ŸNñN³s¨]Z,ðhVÏ%Ç–É"[“¸©b@é‘“õªð›jém©À©m=峨%–ÂâÍn.<¢ rÜa¾`H9„WV<5¤ù7=³J·¢Òc4Ï!’ \…%˜’s#œõ篢ÂZ,o3›y¤’s’I®¥‘ßÉ2,³1?+sïÐäq@~'ñN§á»y_í–7SÙÚ›«›x´Ë‡2(,~ò;U È$ÀéJîûTKßÉq=¥å„ZÍ„QZÏ›þË‚­æ`c~ìmåþnø®¯Uð¶­É;ßÛI'Ú!û<á.$eŒgÂ0 Í‚yâ–ãÂúEÕä·RÛÊd•¢yneTv•‘Š XNHÎ:q@¶ž(Õf¹±½–;?ì«íF]>8UOÓ"«—ݵ²c9P£õ8¦Ûx›[i¢¹š;³›W¹ÓRãu“òª>òÄg1€FÞùÈé[°øcG·Õ¿´ãµ"çÌyW39$`C:Æ[b±ÉË Éç“RL6é¶ýÚ]=â1¸™Ù™›9î]¸éÏN”•á=vÿUi¡Õd‚+ä‰${c-¼g9»*ä`:àpj¦³âÛ3_HažÞâÑo-í&,'fŒÊȹk€|¥`da#äŠßÓ™q§=ªµ¥Ä¯4‘–c—w23œƒ¼–èqŒ`Tšn—m¥BñÛ5ËmÌ×RNÄôûÒ3{f€8¿êz¥¦áK+Ódlo4ÐùHË$^Z&71b2±<Áç­1¼y¨C¢ÂKKÕ]ëR´4û‹xÉ„/Ë™%S½Nä#§lŠì­ô2Ö->(mB¦Ÿ ·µRìBFT)^O<(樧‚tãû¬g%ŽÙ.¦p¶ò`4k–;WåÆ1Ž1@7¾(ÖôË–°¸M>[ˈíM«Ç¤q´ÒùD8,KàämÝÓ­d^}´/‰SP{y.YÒƒIn…Ç™m‚’WŽÙ?Zîït 3Pyê×Ìi!X·°;U·®0x!¹ 9ÔøWG† ˜–ÕÙngŠæf’âGi$Œ©F,ÌI ¢÷çÐ7gã}JëQ-Œ’iÆîkvŠ=6ã|iuóLäyG,œ¨é»ï¤Ó/õmOÄþÔ5±¯l.naŽÝX4!–#±‰c¼à˜çbtÉ1³ÇÌ8þ$'ôî;tôP žÖE­Ì‘¬Vºƒ¬QùË­]ÜbY:o‘s`Êî#=iºƒõ}>éõkW¹MPÞÅ׳J¦6µXZgRû† €Ç×ëÁç¥zß‚¾é·š.çR˜JìÍö«¢Ê2qíLüƒæÛ»¨Î8 ²Š( Š( Š( Š+‡ÕV€B.vƒÕ†õ;H5Ÿÿ ?Äy>tøu+Îé.·4Ã¦Ä a[$6[¨Ã©èÌhž ³°¹–öî!%éÔ.®ã+<†5ó%vVòÉ ¼#Ý·# 8¬!ñ6ûG¸uñŸƒõ-Ð"¸¿‰þÛn€’?xñ¯ÈK ’XgúÃuoż±Í¨9#`ÊêFApAæ€3§ðÞ“qcö7¶aÚ^íLs::LìÌή¬I.Ýà‘ÓŠ…ü%¢½­ªÚÉZ—0É̱J¥Î_÷ŠÁÎãËdòy9­º("óÃ:]ôË,w ,QD°]Ë ´c¢³#㯠ž§Ö‘ü1¥I~·²E<’«nT{¹Z%m»wËl ‚y<ÖÅ™¦xNÒ'–{TœÍ"in.eö‚HPÒ3¹'ZtQ@®¬-¯eµ–â-ïi7Ÿ ÜF×ÚÉž:ü®ÃŽk*h¶Q\ý“OFimÞÝbžY$‰cn±ª±"4'UqÓŠÞ¢€9O xbãIÕo5+¨¡æ‚+háŠök² ´²€ÇïP¾õÕÑEWº°¶½{g¸{[L'ˆî#k€@[21ö–È`•Ýê3Þ¸«uÛŸ xâ[ëk›éîâx¦–'ùA²Ÿ&L¹20ääÏ·ZôkKk˜[G°M3O'ÌN]ŽXóêj…Ÿ†t›¶Kx%ÚÏö‹t{™a}ŒŸ f!Wk°Ú>Qž”ƒ¦k—wÞ °†òÒÎKècÔ¡y¢V\˜¥…F̱ڮ$òÅ2I¶0q"O¿d‡nÊRÃ=0t5?k\Úf•çA-íż—2]G¥\NT  "Ù²KòŰ1îm¯…4q<Ó=¼Ó´ÑÉ-ÅÔ³*¤Ÿ}Q]ˆ@{í‰<+¤ËimnéxE©o"o·Î&Œ7P%ß¿ØàqÀ ~/xŠúY [+ƒHŠþXoa“˜Ï*²}å*§ÊáˆÈÏ çŽÃM½]KK´¾DdK˜ReVê¡”ιéücy¯MswIbtè,ãAu*¹Úò³‡ ‚èÁÓ!‰ÎGJè’ÂÚ;ßµ¤efòD B„ç“× AtÓ¬x“Å-.¯ªZ=¤Ð¥»Á*G6ñ±>^ï,òI9SšË¶ñþ·w¦X›{@n×I·¾³n.>Ñ$ˆE1 DÃó6~÷Cƒ]uMBþæòæÞáÞ詸Œ^̱M… 7Ä#| WµX¾ðÞ—¨MÒÃ,RÇ…^ÖæKrc„&6]Ê9À9&€3ô­_W×5;§¶¶š}œé°Ü@í<ŒcGnC7‚­œ•…g¬ÝiºdÐØÝÛÇs.©©¸‰ôùï@·OÑ!!•r@,rG×é‡T’Å4w?)cÌ‘¬…Fº+r,AQÉáMFVû4ˆÁæ}Ñ\Io5÷È VVnvž=¨JñV§­ÝÚËZ[éçG´Õ&W‰¤—2™7F¤2Ž‘ðpp{ñ—kñ UþÊmZ}5¦µ“O’ñ4ûˆ» ˆÓH6HnP:p9®ÛMдÝ#Ëû ·•åÚÅf¿;6!‹vÅ䞛۞§<“U­¼'£Z,É´¾D±´Ml÷2¼ï*ÄÌQAôP('G¢üA»MZ[9gL$=¤màË'Y˜ðsÎyô,šîªž+—Ní¬mÚO*ÌOc+‹ŸÝîN ;³ò» }k_MðÞIwißi’%…åšæI˜¢’UrìxŸÎ‘¼;¦¾ªº“Ç<—(þj,—R´JøÆám€àžBçšæÇòè·VÖöÂâÃE¸½¿GV"+”Ü‹ÁoŠl÷™Í:óÄ*´—Q„ÿc™,ôåÔ÷y2`©Þ<œoëû³ûΟìVžáXã±×U¶¶óuɤ{Èm¤bvl…cÆI8³VÄú6Ÿs-Ì’Ûî{›Qg)ÞÃtCwË׾܎yë@+Ëi§‚Tc,ŠÖ¶û‚°`ÈÈmÇŽ:Ö­ÿŠ5X.5+È#³þËÓo¢²šF3Ë»ËÜêÁ¶®<Ñ…*wc¨È­Fðn‚×­vlŸÍwŽIÚ%Ù#Fª©½7mm¡ƒ‚3Ô“SÜxcGºÕ´¦µ-s½$lLâ7tÆÇhÃlf\  è(޶Öõ="ÆSoå[ØOS{‹ÙleºXȺ|+,l¥Žó6×i¬jbÇC{Øîíá'`Ži"i–`g'<rIÏ„tk¨š)!¹XÝå‘Ò+É£Y Œ]÷p$àäsŒb¯ÞéVZ…€±¸‡6êPªÆÆ2…H*U”‚¤0AÅqÖÞ/ÖoÞÒ´§YþÍ’iìæ…JVœH!v§Içº?ŒuCR¶ kçZIy%¤‹—r…O;Î9“îo¼H5ÒÚø_H²•e†ÙüÁwöÝï<ŽÆo(ż–bIØHçŽýy§EáÍ2 Mµcž)šC+"]J±=XÄacÔ¹Ï4OÄúÍÖšÖÐØÝÛÇs*»ˆŸOžñä Ž‰ «’2Ç dqTm¼M©ëqè+¤Çim.£¦iJ×hÒ*/îñ…e9&O½žès[ÚŽ‡§ê“Å=ÔRbF^)Þ"Q±¹NÆ”íŽ*ð¾l¬,ÖÚHⰋȶò®$ãlÞ¬© ¹œàg¥y厭«]|9¹±±[(¡²Ð<ûŸ=YÚS"Ëò£püÄ6Iè1šë|I5ü°}:ìZÏçØ'˜U›†ž%#åe89äg‘‘ß"ôž ðô–QÙKd¶û'—Ĩpµ†õ8 œdã­j]éVWÚYÓn!-hUW`vR6T†A‚AÍjšö½k>¥ £i®Ú=‚^]´Ðº‹–mçbÿ»ŒüÇ'§¯ëÚÖ£o¤é÷š]¹òî]LÓ5¤—FÞ2…ƒyQ°fçhàñœÔ÷žÑoü¯µÛÍ1Ž-w.eŒ„”îÌ«’x}ÓêjÚê±GɹAÊ›k©mØq½)Ƕq@W.]:6úîâÖ}*êÆiZêehÓÌ‚N"Èpy1šÆ+ñlv—·SÛi*lnm-æ¶Ù gy〰¸…ØÓuÁÈS»­xV=FÇHÑ­í-#Ò-n#š]ÎÛÔFAUEÁÎîCÂzçi´-6qx%¶Ü/'Žæ†ù#ºñ-8qÏS@–µ«ëÍ£êVfòÖBÇU°‹í6ðÈ©$rË ÆÏ3#ïÃq nâ}GÅz†•«An÷vw±¥Ýµ¥ÔvúmÀØÒ².ã6æ2ØÜãäŠén´ 2ñ/’{bÂù‘®‘”³&6AÊ‘´`®9ëTσt6‘]íœ‡½™ƒKR’0/†q±~c’qÉ4ÍèZ¦©¥«Hßc}2^Z‚7œ ÝJîÝŽãnÞœîí[:.½¨Ýx‚{ Q ´}Óy6me*;"¾ÖrÅ%pHPÜ3Ò¯[øKDµÔ~ß £‰üù.pn$dóœ’Òl-·qÜ~ld5§‡tÛ-HêG;\á‚´×RÊ# rÁتgî@—‰n'Ó¼i}¬Ì–WPi:0º‚ mÉubÒ–BØBJŒ¶ÓòñŽõgRñ7ˆ4cucrºeÆ ÎH$Š)#‹\¬,¬¥ÉÈÎCÎz `õ“éW7Ïl’ÉqmöY·’UâÉ;JôÇÌÝ»Õ h¶ÐIZÈâG…Ù¦¹–W&'ÜÌ[j°È\㯚‡_Öo|;᥺—Ê»¾y¢·VŠÞ@›¤(>Z—r9À$œ`cal’»Cœ`óÓߨZêvRYÞ³[ÉÈxèr#A‚9TG†tÏìé,].¥…äYKM{4’R ²ÈÎ]H ‚1@ÝŒu[ðšl)lº›êmb.'³š‹q?˜`r§nÒÜžsŠƒP¹ñâmbîÞ]6K›] Þ{†x$»%º!UCå23É-Œt9ã¦ÿ„CDû,Öÿe“\ §“í2ù¾pP‚A&íêÛ@wõ5b?é‘Gp‚í¢Òf–yž \€Y˜œæGç9節*ëÚÝÕ—…âÔôø¡k‰¥µHÒ|•ýôÑ¡Î0z9ü}zVdþ&Õl¡Ôm&[9õ/­¬à•#hâo?fÖe,ÄmÜrsÓcÓrX\ð¯Žt_$©c,–÷ð;¥ÆvwP`§ty'#‘‘“ƒÈ t•OUÒ¬uÍ.ãLÔí£¹³¸M’Äý0AÁr`й\ŠëzƒùwKÄ’AO1Ö2ÊA0H=ˆ¹áÍÇÂÞ³ÑtÕZZ¡Tós1$³1>¥‰<`sÀЧã ÿÂ]à½SCyr]Eû§-€$R7—r®p3Œãš§àϯˆô½R8ìñtöºý¦Cœ/#'dÞNÍÌË» e°2Ùð÷KÕ}kÅzå—ö~¥¯ËŸaŸ³Álˆ6FD„[ðáNTGñ2ÏÄÞ"ÒÇ…ü5obùÛµ åh’Þ.¡.\©Rv ph‹ðí§^m¶ñ]Ÿö|Üÿ¦Z+<'ïS—^Ž7ä’~Q[ŠšoʼnÐÜ^Ç}áß ¥»Ãi «-½åÄªÍæ¹ lÙÈÈ<€YZOü ð·‡6ÜjIý·|3óÝÆ+÷‡dƒÁx·*ÅIw©CàŠšŽ£¬,‰£ø¡-‘5ŠÖâdHsÀeù·œè@fPL¢Š(ƒø›á¨nôi|Seq&Ÿâ ÞK«Kè@ÜU±‰ÇFF=7 ²¶†“ñºŽc{qâ Î{‹xå’ÚMF-г(%H9ã éÐVÄßÃi£Kák+y5k¶òZÚXÂF஥L®z*(ÉÉë´ô™t4Ÿ‡Ó´k+èדÛÛÇ—2iÑn™•@.r É#=O^¦€.Âwàÿúô?üÃÿÅTsø×Á·6òÀþ,Ñ‚H…ǪFŒá•ÁSî#µIÿ'ƒÿèTÐÿð]ÿQÏà¿ÚÛËqqá¯ÃH^I$°…U ’I\9 '³øçwáo]hž#šÓÄvp>#Ö4¢¤R TŒ~dR]»[—<žóÄŸô³ðÏYñ…õ/f¶‰Q66×ä)]‘—#–—æÛès^a7Â}gâ'Š.5hôˆ6ž5{(¦|ý‹2”x”œ–RHa“Æ:KDžxmm常–8`‰ É$ŒQ@É$žœ×ø:ëþ?ˆzìíçƒF‡OE”³&>Û‰K¼ª ¨ (Èç=A@¤QEQEQEQEQEQEQEQEQEçÿÿæJÿ±®Çÿg¯@¯?ø§ÿ2Wýv?û=zQEQEQEQEQEåú.»£èŸ¾ kj¶6wöw—ö»„‹~-Îq¸Œã#§¨¯P¬{ï øoS¼’òÿÃúUÝÔ˜ß4öQÈí€Ë“€ü(¿ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ü'~ÿ¡¯CÿÁŒ?üUðø?þ†½ÿ0ÿñT àÿú4?üCÿÄÑÿ'ƒÿèTÐÿð]ÿ@ÿÁ/ù$:ý¼éD••¯iu®x‹P¾]>å­5 >;gk?ßB BÇhÃ6@$玕é¶6zeœvvZZÇÁ$“… ’OãU§Ð´Ûƒve¶ÜnåŠiþvÞ=»^1±zuÇ4ÍÿÂYz|Oo§Ãqkskys=¤Nš|è°È‰# ÌO—/1•e]¤¡¨On²¾Ø¶³Ùé2^j1r<¹ÃÖ sÀßÀ“žº(¼)£C¨C{´‚h'{ˆA¸¤r8`ì¨[jç{dŽsÖ¥·ðæju3Œ`jŒZô1,&$r “ÀÀäúšÀ¼ñ·£[kÐêOžöÇHmJÞKx#$ùK“à äOÓéŸo6JúŒ–Ï;üØ·‘P>^Xî çæã>‚¨Áá=ÚÆúÍ-dx¯¡û=ÉšæY]âÁ]›Ù‹›N1WcÒ­£ÖTÍÃ[%¨üªŠÌÜ{’Üÿº=òÍøËÅw^7ÚOo/Øí~Õ=ŸØ'ÙFãÌ‘°‚áœ{ mˆ/u™ã[ìí2úÚÜÆÑ9–T‘!f;·aHóI)Î1ÇSµªø[GÖäïí¤“íýžp—F²Æ3€áÆæÁ<ŒñV$ÐtÙ£½ŽKl¥ì©5ÀóçtªzñtÇOs@uΩªê÷šô¢Í4Ù5׆ULžX™3Ãga;BŒdry®žöà'4{o³ÂÆK+·2éµ áNpÝÏÂ:S¿áÑ¿´c¾û+ùÑܨǟ'–’œîqí Í’99ëZ2X[K¨A~ñææÞ9"‰÷•\©aއ;¯§Ö€9_ x“YÔ‡åÔÖÀǬصʥ´N¦P‚YŽàCÃÇ=j kUŸIñ¦¡%¤q½Ôö:u¬>nv+És:lsœàuÆ8Íuº›dšr[Ûl]6 ÞÇËB‘Éç…œž)/´ 3R’æK»Q+ÜÃ’ì2ˆÌéŒf$ƒœsÀ pø›Z]Kþò4ó«ál·~Sˆ<³›y~íØvï÷Î8«ºæ¯©éVövâþÇûJD‘ÙSL¸¸óB‘ÊÇ–Eäe‰`2:ÕßøD´_ìö³û,…´™M̦o7ó<íÞfìqÙÇ*I|1¥N–Ë$wÛ#F’}®`å‚Êï»s‚@$1=(àÖüJuQ•ößi÷^s·{Ü63íš[ÿj°\jWGgý—¦ßEe4.Œg—w—¹Õƒm\y£ TîÇQ‘]›¡iºAŒØÛy>]¬Vió³b÷l^Ié¹¹êsɨn<1£Ýj¿ÚSZ–¹Þ’6&qºcc´a¶3. Œ t_ÃzŽ««5õÍÛY¥¤W—V°ÅM¼ˆ¦d ÌXŽ‹È ×œö¬˜|O­Mq¦ÞÓÆ™ªÉ`°˜ßÎÊ7–Ý‚I‹¦ÑŒ÷®¶ÊÆÛO…âµËGšIØn'/#—sÏ«1?ÊM/‹-ïþÉikgox÷›£¼šF•ʰâ8‰-–e$¶=ÍQÑ5-SíhÚCYÅ<·º¥Ô“ÝÆÒ(T»e YI$¿\ðCš«g®kž³s¬é‹ao#ø~Öâh®CH ,·?"•eÀ'wÎsŽ>Sž; è·Q*=¬‰¶Y¦W†æXœ4¬ZOX6œ•Î:qÀ¨®¼áû¶F’À¦ËT³ òD¦$ˆÈF§Ìr§ƒÆs@Søêqwcqm$ÙO5¤RÛ-„ìðùþX®ò•‡˜§a‘ŽrEmxþFOØBý$‚§ŸÂZ%ÍѸ’Ñ÷£¸(—$~l{v?–.á±yÇ `ñZvöÖ·7wǶ[¹³¶âw°E@yéòªŽ=(”´ñ6°n ¹ºO—X¹ÓDi‰£Ê«!rØÿ–`·¹9+9¼y¨C¢ÂKKÕ]ëR´4û‹xÉ„/Ë™%S½Nä#§lŠì¿°tÏ&8~Ê qݽâ©v#ÎvffëÎK·9éTSÁ:FñýŽVF³’Çl—S8[y05Ë«òŒcÇ  [ÏxªÒ]FýŽd³Ó—SÝäÉ‚§xòq¿¯îÏï:±Q¿Žu+Nãì2Ikmq -nºuÄÒLQ„È<¸ö‰8 vòW"ºùôm>æ[™%·Ü÷6¢ÎS½†è†ï—¯}¹óÖ«7…ô“x·k ñJònådØ]ê¬ð0< Pp×µü`Ú}ãAefÓí–K)XÝ/vVà7–­»pØW8SëYzoŒuoìmSÕ¥Òâ‡U±’uhãu[gXü̹.w!çp2z×PÞÓ_U]IãîO5î¥h•ñÂ"Û`žBçšÆð÷€´½3ÃÖvWö©qr¶ÎßÈñr Iå« b2J…'©  è|o©)¾²xḽG³KYžÆ{8Ûí4`´r’ØR„ä6@9­=o\Õô=>Þy-®/ﮌ+qo§ÌñÆËy(Ìì~\`0뜀 h/„t@—Šö²Lo#Ž)ÞâæYYÖ2Y>gbARÄ‚Gð*WðΗ&š¶¥Ì±$¾r<·“<ÈøÆå”¾õ8ã!º(¾Õ/µ=î.ìÞ+¨ä’<4@& ~WTnPÃ8瓌×7mã Z=&æòý­VêÐC=å‹XMo%¼±)܉®HuùNÃëÇgi§[ÙXýŽ9¢9É–w•ÎzåÜ–?‰¬yü3 Ž›~4‹U¸¾ºƒìùÔ¯f•vr6–mìn'hÀ'Өθñ6¯q Ð<›hÖÎXÅ©˜Àñ]ÍÆf`òêÁ¾b=zdt$P·Œµ[‰l&¹Km:ÆUD’w³–xå›ÍhݪÁbQ´¸9Ü+½¬6ðŽˆßg_²Ê°Ûª,vés*Ä9]ÑØØ#?05«kg’Ê VQ,­3îvl³“É8Ã@ÑEQEQEQEQEQEQEQEQEQEçÿÿæJÿ±®Çÿg¯@¯?ø§ÿ2Wýv?û=zQEQEQEQEQEQEQEÏø“Àþñw–uÍ" ¹#ÀY²ÑÈÎzÛ~bvç9Æk ¢€<ÿþ—ÃÏú¿òvãÿŽWa£hz_‡´ä°Ò, ²µ\¦7ÜÇ«6Ë“ŽMhQ@GYÕmt-÷U¼b-í!iŸd€3’O@3É"‹ gLÕ6±Ô-n|Ä2(†erTÁ<ÇÖ€/QY‘ø‹Cšxà‹YÓži*F·HY˜€@9'¡<Ú¾›o¨E§Í¨ZE{0ÌVÏ2¬Ž?ÙRr ¹EV½Ô,´è–[ëË{XÙ¶«Ï* 'àzàôÒ«Éâ xn%Õì Ô¼25Ê‘A•9Á²Ž=G­hÑTãÕôÙu'ÓcÔ-þ1¹íVe2¨õ)œøTqëÚ<ÒÝE­`òZ×(·(L u.3òþ4¡\ÿ‰<¡x§Ë—Q´Û} ½ý»®`a¥$ü¥‹r¹ç®Ÿhk¦ Lë:x°-°]¤ò‹zoÎ3íšuÖ¿£XÚÛÝ]êöö÷#0K-Ê"J1Ÿ”“†àŽ”È¬ÿ©÷Ç?ø8ÿì+CFøm¡izŠjw’_kšœxÞë7æHTÊ *á ¸<ó]…QEQÖu[] E½Õo‹{HZgÁ àd“Ð òH  ÕOUÒ¬uÍ.ãLÔí£¹³¸M’Äý0AÁr`Šm†³¦j‰Xê·>bC2¹* àžãëQGâ-iã‚-gNy¤`©Ý!fb äœ~„P>kúMï…¼}©iº{"ªÙ^[­ú«üˆ€^9'Œø3â ͼ°?Å H…Ç¢BŒá•Sî#µwjúm¾¡Ÿ6¡iìÃ1[<ʲ8ÿeIÉü*-OUþκҠò|Ï·Ýý›vìyº’MÝ9ÿWŒq×Ú€3<5à#ÃÞÀ×wº¥Ê¸Ôµ Ì÷¨<Ç€Ú0 d*ç8ºJ¥m¬iw³\Ci©YÏ-±ÄéêÍûÀ—ñ¤°Ö´­T°Óµ;;£'ìó¬˜Æ~R{Ðê(¢€ (¢€8ÿü<Óµûɵ[+Ûí]’/(êZlíºò¬€s´žŒv(ܬÿøD¾!ÿÑOÿÊ¿ø× Q@v>_kÞ3ñ†¥¯ZT'Ø­ÜOï6ùÈb¤‚ Œä`@‚mmâ··Š8`‰GjQ@ÀŒT”PEPEPEPEPEPEPEPEPEPŸüSÿ™+þÆ»ýž½¼ÿâŸüÉ_ö5ØÿìõèQEQEQEQEQEQEQEQEQEQEQEQEQEQEW¬½+Äš¦´º»éBxšÚêÂø¤6±áÀw|û‰m¯Ã˜®ò±nü)£ßß5ÝÔÊìë#Dnåò]—-턌«Ú€9‹-_Ä:w…µ+ö¼³½›ûií-ÒXd]»¯Ì'-æ”ù@h|Ø©õmgSÑõ;à‘i·’ÚéÉö!ãy×’E´ä…Pr9<’yWGÿΓºç÷í¹¸K™#ûLž_š² ݵNðà ÷ÍMw¡i·×2\ÜÛo–AfÞÃ" ±ðg$ûô9P8þ$Ö×V::yÔšø@—fˆÌbÆ=ù-Á\oç¯*?øI¼@Ú/ž-­¼èõ9ìîg·³–å"Ž2À?’Œ²UGŒûVÆ»áØo"šk]> ï%ž9˜Ë{-±ÜŠT2É,Œ”r ­VѼ¯‡ã°¾i_´KrÆÊîhB4Ž[huev2zã$s@ê÷óÝ|9¾Ô,o­ÞfÓ¤•.¢‚’UwdwÆNAëœW=e¨jº&‘=–•Z>›õÊ‹V‰n ïm¨ü‡lg.weJîH°Mé n«`a0T6‚3œô'œæ©êÑu7®íÊB !g‘‘’`$^¿+dr}MTÐõOZÖõ,H´ËIbDC¤ßo¼¶ì. ž‡#Ž1“šîªž+—Ní¬mÚO*ÌOc+‹ŸÝîN ;³ò» }k¢¶°¶´¸»ž¶Iw –c’w0E@pz|¨£J¦ÞÓ_U]IãžK”5K©Z%|cpˆ¶ÀpO!sÍsã‹ùt[‹«k{aqa¢Ü^ߣ«ÊnEˆ`Ž7Å6{áLæyâZK¨Â±Ì–zrê{¼™0TïN7õýÙýçOö+OFð¬qØë‹ªÛ[yºäÒ=ä6Ò1@Œ»6±ã$œY«b}O¹–æIm÷=ͨ³”ïaº!»åëÇßnG<õ FòûU>/Ôo´†²Lh6—.·h͸ .Aµ†ÜäüÜペrxÓS»³Ÿ[µ†Ñ4‹k‹x$·•ÜIæ,LÌ0UÛç )S»iädVý÷ƒô=Fq5ͤ†O³¥¡)s,{¡RÄFÛXn\±È9¾p*I¼+¢Ï©-ûÙþø29U•Ö6dÆÆhÁØÌ¸$01ÐPm­êzEŒ¦ßÊ·±:ž¦÷²ØËt±‘tøVXÙJ ç m®‹Æ—7©áx§Ó/R ^öÈ ‚³¯qñµ”àîçžW#¾E»Ÿè×Q4RCr±»Ë#¤W“F²»î à0,IÁÈçÅh^évz†šÚ}Ì­X(ØŒSnÒ í*ARAÅj—:îâbîÒ]9çµÐm§¸i`p²”’äíU”Ï<’ØÀàæ¬_øÒâÛS¶ky`žÎK‹X&·[ÙâóŠ µÀ>R°óí#$cœ‘]2èpYÃE$†âÑl¥ig‘Ùá]øRÌÄ“ûÇù³žzð*¤žÐä˜HÖ’q,Sì2ˆüÈöìr¶–œdãœÐOI«Mg¨I¨ßÅtƒQ¼Ž0!utÛq"ãs;ep´2j®³âÛ3_HažÞâÑo-í&,'fŒÊȹk€|¥`da#äŠèìt{-:êêâÑ%®œÉ*yîÑî$’Á *¤’I*{Õ[¯ h×—u=´#ÏË(¸‘c2ÆT«” ·pؼã'9 ^ãÆäA‹5K­VïO·ØOpѬ/'ïcmÎq6€9;·1]W†õ;ÍWIóï­ž ÒWˆî·’ SêIó(#§#'­:oiSØ›7¶aÚ^ì•ÑÒgffupC)%Û¡HéÅ\±±ƒNµ[ks)Œs4Ï+’}YÉcøšáâñ†¸¾ÐoîEŸÚµ½†!oa<Ën¾SHÌQ¼„…n2rHª³Ýê:öµáé5;{t‚ÜÝË$Zl Lb)‰Q$e*J·Ëv’~õvÏáÍ*MÓI6̶va°I]^£ V@w‚<ŸZ’ÛBÓí$µ–8åimD‹“\I+øÝ–f%³´uÏJâ ñöµ&‡qªý…^'Ò§¿ˆfÜĖΑïDy_ (aÆSo#ŒƒšÓÔüI­é×Z~œímö˨$ºy¡Ó..R$]€'—c—ûä¨Àé’l'ƒôHíîm’Þqms Àöÿk˜Ä±¸Ã*G¿jdáªæ¥¡iú¨€ÝG({|ùRÁ<È€ã :0`Fpp=(”oøŠâ+™!´³²6š4zŒÐ^A!s!iƒG÷”¨>WŒŒòxÖÒ5W_Ônf³k+}6Òd…ãšy¥&4‘ˆ`à&<ÀU³ŒñšÔ]LU~ÎÍö‹E²”´®Åá]øRIÎxüõ9ëÒ¢_ éQê }3E:ʹ•Mƒ ½r, àP7§øÏUÔ5D0X<¶R^Mj!]>à4jŒê%7yDA•€ÝIV§„õÛýU¦‡U’¯’$‘ìEŒ¶òAœäìD«‘€ëÁ­ðΕü—‘Å@àóß95%¯‡4›+{8-ívGgr÷p1ÎÉ_~æÉ<çÍ~G>€9ë_^¯‰¬4ùnm/­®îe´2[iÓ±Ȉí‘33FüÆÀ¨9׳týKS·K)õIíoâ>!½†<Û¸’ŸjåXÈ{&ÕáIõ®º/ hÐêÞÇm š Þân$)Ž;*Ú¹ÞÙcœõ§Gá&+ÿ¶¤‰EÉ» nd1¬¥YKˆ÷m‰8ç'šåeñž¹e¡¦§uœë}£\jVqÄû†Ž1"¤„·ï 2Ãg#ç5ªuÍ~ÚMJÒKk;ÛèôÕ¾µŽÝ0X–6ÜÇw*0ÃnsÐUè¼ CÌ)bÞUͻڲ4ò2¤/÷£ŒÄj}oAè*ýÆau4³Ky²Û‹ft•Ðù`’ Œ’r9÷ BûXš÷ÂÒßKy Ú†›¨[ºˆìe´x˜ºŒÌ +²ç8!ø®ú±šdQ$Q Â}ª;¹L³¼Ï;Ç÷7¼…˜€B3ü#¶kn€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿâŸüÉ_ö5ØÿìõèçÿÿæJÿ±®Çÿg¯@ Š( Š( Š( Š( Š( Š( Š( Š( Š(  ¿XMªø[WÓ­öù÷vSA㹨Ïâk•ñ[j‡IÒu++Il5v‘´Å†wBág3”fk¬ru臥wÕ^[Iîà»šÖ .m÷fxÁx·pÛXò3œu 7MçÏñO‡ô'tugoà‘[,vÖø, vŽWh<ç§Z½áJOj‚UÕf²Ô/aºY,ÞÐ"lXÀWÍJdl'Œc5ßGo 2M$PÆ3••@.Às…'°µI@ŸŒ‹uáwŠÏí’&°@Al[Nx,@Ü1‘’@äuªz'‡õñE¦¯y` ‰›P›ÊgF6Í+@N ˜G#¹±çžÒ[xfxžXc‘¡2&u£`®åô8f‰õ©(Ïàðö®e²ÓMƒìš¥ÍójÂXÈ‘dóHÚß¼ùЬòx¦>‡¬\øÓÃË£Égq¦­±3$°˜G’ß{ioÞ ÆsɯC¢€<óûóË}Gì$:‹Þ ÖO;OÆâ#𠈈*vœäð=*}OOñ éº]ÚY]ŸÅdñ4ö/l"Vm¤¤©)ÁRUI( àâ»Ê(¢Š(¬¿XMªø[WÓ­öù÷vSA㹨ÏâkRŠà|VÚ¡ÒtJÊÒ[ ]¤m1aиYÆÌåÚëz!éY©£\ùþ)ðþ“¤îî¬íã¼"‹eŽÚß!ŽÑÊíœôë^‘-¤÷p]Ík—6û„3<`¼[¸m¬yÀÎ:Ô‘Ûà “I1£ÌÁåeP °AcÜá@Éìí@ ÿ†5)dC5²2$ªèNÖf*y Œž™Ï5ÄÇ'ˆ'þÈwÔ-.%ÿ„¢ò( °Iû½«x¤“æÊùPmÀg½z—¤YhðI”N¢Y ’<’¼¯#à ÌîK1À$žZ? é0êõ ”L.MÚ´ÈcYJº³ˆ÷m‰8ç'šçnÞÂÌZB%h¹ÏŸ3ÌÍž¹g%âh‹µñž­5Íŵ´vú¤’é³^Ù463Û#´eÀÒ%ÌRéÐdTSëZΣ&†–ºÍ¢]k˜'S¦Oo´i\,¼¡ˆã=p~R>ï=, Ðí™Z+iÃ%»ZÆMäÄÇ%—ùFQqŒcbÿ†‹öV·0ÜÓ ƒ9½˜ÏæÚÎßæd)#ït$w  µÜn ¶9 `\t^-¹ÿ„²ÒÀOowcyw5¢´6Çä²$þ½‰ŽCû¶R«‚® tš^•o¤A4VæCç\Iq#HۙؓϷ{ÔóU"𦡠ìvÒ  î!âB‘Èჲ¡m«í9ÏZå!ñεgáí?XÔ °™/ô©oc‚Ù3ˆ¨ÁK36U·z ¿íu­Mj‹ñí5ilåœi0ö‘´kƒ,œmfcÁÏ9çÐVØðÖŽ,¬ìÍ’µµ³Zó2¬L¡YNOÌ €9Í.›áÝ3I¼’îÒ)¾Ó$K Ë5Ì“1E$ªåØð ?sÞ,ñ~¥ ÞÝÙZZÛÏr`Š{$uoÞ€diÔàòBE‘ŒrÃ9¬Oøµ;Wqohö¯¥ë)ipª|Ï.%…qó>üñÑWÐçЮtm>óT´Ôî-–KË4‘ “ò,€Î@}ñÔÕ¼ Ã¦C¦Ç`Ò I¬ãŒJüC6<ÅÎrs´s×Њ©¦ÿÈû{ÿ`[/ýqX’ꚦ¬øÃR¶ûXÚßÛ½Ä2#eÚÜ6Æ 9 “Çk¸‹Nµ†ý/[³î<Æ…ŠŒgnzóYÓøKD¹ÔåÔf´v¸šTšoô‰Jè!t µ¶…\g©&€0tÏjz–±—dïa-ô¶†4Ó®7DˆÎžiœ(ÉÊÀo¼H"µõí[S´×4ý?OkHãžÒêæig…¤*"1cj«.sæ×ÐöÁ»‡4È56Ô!Žx¦i ¬‰u*Ä\õcm…Rvç<ÕÙ,m¥Ô ¿xósrEî?*¹RÃJ/_O­qþñv¯­Og$¶ ö×Ö­p4ûˆ±ÀdFšA²MÀ‘¹qÈàsPÛxÇVs‹£hºÄ’[B–2XÍoögš@™rÎ|ÔýäÀ%qÆxéì|3¥i²³ÚE¦€9Uñ†¹rÁ-¢K<¯oµËé·6¬’Ê#*Â^[nCeHÝÓ Z~ûhñŠP{y.æÒ[¡Dqä&RI^;dýkF/ iYÍiå\ËÁAYïf—nÓ•ØYÉLÛŒ1Ò­iš%†Ž×/e«Ý8’w’g•¤`‚YÉ$àøP)aªI¦xväÁw¼ók—ñÇæÙËt_ý"bBÅ Ç<&ªÙø‹YÕõm ò;¨­cû.¢.íÍ´¥dh'Ž6! ©R@ùC ¦X玾_ iRÀ›y%Ì—hÑ\I¬².ÁÕƒ ïl€qƒŒb¢‹ÂZ,ZG´°‹Id–ŠêTei{åƒÊÍÉRHRH8äp*æ§á=W3}²ÑÙf€[J‘\IÉΕÆãŒŽ3ÅfI­x‚kÏ›,æ‡K`–öþ[nÛÇ(·€¸gô9py9ÒøÖö+hVâBâôÛ1]å °ûmÍ#/ sœ]yѬv_ ‰”_°{‚’º–`Š€‚TíE.:g­RÑE¤–æÞgß0œÌ÷r´þ`C ‹y€ÀÃp èÞÔ¯õmæ¹€Û^,’D­%¬‘+àád¾);Iõï\¯…õoÉ¥øRÈߨNúŽ˜÷Osqm#:ŸÞüìL‡'#±Ç=ÝŒuªÛ[™L`“™¦y\“êÎKÄÕ;Ã:N“q ÖpJ I!îd‘bG(YQYˆUýÚpc&€9«/êWzˆ™ld“N7s[´Qé·ãH˯šg#Ê9dåGMßxEMá_êºÝÝ‹\Y·Ù/­Œà¦qµ8 ªÒÈ6KO̸äp9®†/ijm SÇ3HedK©V竃l,z“·9æ;Úf“qçXÇ<\X¾Õ+E=BFX¢À@  ½g^ÔtïÃlí––Ë.f²–e•ÙÈdó‚ÂGË‚à‚Z±4m_SÑÍ ´}*}{P·1¬mçŒÏ;o »oÞ\mÛÓÝ«¯¾ð^­ÕÜsÈêTùj•bb§*Z ÛÔ‘t-5#Š5¶ÂEv÷¨7·;33uî]Ž:sÒ€0t/ê÷Wz9ÔRÄÛëVown¶ÊÁíð‚9,Cü¯÷€^GNk\ñ5æ£ðòÕæŽÝN±á«»»€ŠF×êØLž\õÏnk°Ó<1¤h÷FæÆÕ£“a7Lî±! ”YˆI…p=*°ðG‡Âºý‰Ê4Ûk™J¤RŒ: -„R1ÂããÌx‡TÕuP‹4Ó,oìí7Fó¤mð1pÛ¶¨À ´çädVïŒÍ×Úü.,š¹:¾§‘smp NN23Ó#­h^xKE¿¸i®-™Þ7u[‰ãÆÆd ˜m^HÏÒ­jÚ-†·ê´‚Þa<%exÙ$ Ê ‚zuêr·>3Ôm¬âµx¡:›jriï<6“OÙ“Ì¡.r¸wpIË`Vþƒ¬]_hRÞj6²C4"¶mä‡ÍU'©'Ì¡†C‘“Ö¤>ÑΕ›öVñÊgFÈ%Y $È% ¿yÉËnÏ'š½ccj¶ÖþiŒs4Ï+z圖?‰ 8¾ñ.«i.â]J+9bm"òú {UedÊDÂ6bNî üÀüV¢x§Ä†ÚñSO72ÆÈ— ¤]@ˆöÈ<©iJ¯Ì6[ž9߃ÁÚ ¼«"X–Ù –è’Í$‘¤OȨÌUTà| Å:? iPÛIn†üFûzêW“o@ŒdÊe"€9ëmWWÕâCzT³øoI¸±ûÛ0‹í/v¦9&vfgWV ¤—n„pHéÅc[x¦øZÙOy²¢j’i—ïm¡²È’&O¿–9ÆügŒœçñ¶§ºW¾Ó/ᵊX$O².Ûw·žH$‰pUxÙXÈÎ¥qš¯ˆµÍkÃz¼pÙÛXý›EûEì7‘Iæ;H²‚‰’¥“¹”ç#ƒZž-[—øovÒÅ‘mc“ÍŒ¸dgE+€Ë×<óÈÈyáPˆEsm+§ÙþÌøº•L±sòÈCã“÷³ÔúšÐ¹Ó,ï4õ°žö˳ ¸¸C/ ç‚£ò ØÀ2¨Cgxf©hr¬%´™+šû:à^Fk±¸ðÆuªÿiMjZçzHØ™ÄnéŽÑ†ØÌ¸$01ÐTÖÚ›iwÔÛf§emìpgpòðN>fP}»`P"|]ât«kÙ Ó¥mGK›P³†$pbdEFä·Ï•lnpGCšu¯ŽîïµÃgm ³[Ý^Ã! L°‚ÿh'ž«äÉŒp2¹Ï9étß èÚMÃOghQÌf%3ȱ¡9)±"5$•@Jm„´-5´¶³ÓÖ#¥Ç$Vg{)dûã“Î}NO_S@ö¬ê—o„l´¨´Û%¿Òd¹“té–! ¨¡ÁÇïÁ>œñƒñ¦¹¨h÷wú|:t'OÒRúæ;„wóda'È„0Ú£Ê?1ÎsŒ f»= M°ûÙ­¼¿ìûvµ¶ùØùq6̯'ŸõiÉÉãÜ×3â/‹ë5°Ò¬,â…­ÐÜK}:4hI<Æ ‰ÀÜHW`Ï­]ñeæ¢|kuct¶—RÝXî}ŒFx2œÜŒò2;ädê—:îâbîÒ]9çµÐm§¸i`p²”’äíU”Ï<’ØÀàæ»;­&Î÷Iþ̹ŒÉkµWÊŸ”‚¤2A ‚*%Ð4ೆŠI Å¢ÙJÒÏ#³Â»ð¥™‰'÷óg<õàP&þ"ÔmN}.ÂѯáYîVÎK¦Dk8Ü;Ås’©òãWJÚ¥Ô¾mOMjWfÐË„Ißo’=‰ÏlÑ'…t™EX®a2:ÈÍoy4,YcXÇÌŽ6"Œgg­\M&Æ-!t¨¡1Y,~RDz_fp>ùÍq3ëZΣ&†–ºÍ¢]k˜'S¦Oo´i\,¼¡ˆã=p~R>ï6nüeª®¹{oifÓÁau¬Ç¦ÜÊóåQÖUÌqà? ÙÎÞHÈ­ïøD4_²µ¹†äî˜\ÍìÆ0.ÐÞvÿ3!I{¡#½M7†´¹µ·îàí.b»–5”¨LЬB,€0m)ÿÌ•ÿc]þÏ^\=‡Âišµýž…åÝZÊ“Bÿkœíu ©Á|:×q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@yÿÁ/ù$:ý¼éD•èçÿ¿äè_öñÿ¥P QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWŸüÿ’C¡ÛÇþ”I^^ðKþI…ÿoúQ%zQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@oñÍOÇ~ ÐáÖµ].Öÿíßh}6èÀíåÄŽ¼ŽîSëV?áVÔûãŸüöx·þJ÷ïû‰ÿé:ÖŸ‹¼Iq¢jºUœZ¦‘¦CwÄ’\êq–@còð£& Þ{ž(3þgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþµ¬de~eÆNNàjůŒm5 Ë{}6Æú÷Ì‚+‰1ˆB@.Õº«d(b1@?ð«?ê}ñÏþ?û ?áVÔûãŸüöÐ[øºÊãRŽÙm/Þk™- ¾d_"Y“vävî¨À §ñYº"oÇyª´Íwm¤A¨\¸Gœ[”ÈÃãÔPøUŸõ>øçÿý…ð«?ê}ñÏþ?û ߸ñ}¥½äµ•óAo,pÝ]*!ŠÚG B?͸ŸrT0䊡{â÷ŸTÒ­ôû{ÈífÕM›^4haŸbÈä°Ã'R;N   ÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ßñ~µ£ép®o έw0†Ò²UˆRíœpñÅfjþ3t·Ñ.l®ìtý?R¶kƒ¨ê4ÇÂŒ…d›y9fä=MSÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°­êž#Óôk=JÃPÑ^9Ö g$ªï4Éôa2ü¸p@Áéמ:{¼ŽÎ5Ô'‚{¡ò[ÂbCÉÆ³Æ?ˆþ(‡ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ±}ñƒÀ:}ä–³xŽ‘1“RL‡ ©ëØñÓ­?<¨^GkˆàI83Å$(0 åÝBŽÏ=:ÐøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½ŠóÿøUŸõ>øçÿý…ð«?ê}ñÏþ?û ô (ÏÿáVÔûãŸüö¬ÿ©÷Ç?ø8ÿì+Ð( ?ÿ…YÿSïŽðqÿØQÿ ³þ§ßÿàãÿ°¯@¢€<ÿþgýO¾9ÿÁÇÿaGü*ÏúŸ|sÿƒþ½Šòÿ éמøÉ&‡ÿ ¹ªX¿‡ÍæÍNô϶Cp `ÀôÏ'žkÔ+ÏÿæáîTÿÛºô (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+Ïþ É!пíãÿJ$®âû;‹Ë›8nà’ê×oÚ!Ix· ®å®G#=k‡ø%ÿ$‡Bÿ·ý(’€=Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ?ñoü•ï‡_÷ÿÒu®®ûEKí{OÔ¤‘JZA<&p“ÍÙÎsÆ6tÁÎk”ñoü•ï‡_÷ÿÒu¯@ "‡q<6J³ØÜ5‡²ê:x¹‰m݃,e ƒ”À ÀŽ8 Ô÷ž {ÏìøÄú\ÙùeßKÍVÜ|—ˆƒtÆÖàŸZì( Z×Â3A{l©‡Ò­/d¾·´øHåÎMß2#6ƒÓ$â«Â†ÓÖçQ!t˜c‚ãñy4nß/Ïžüë²¢€9 ¯[KâR8ô—[©’y–÷K[‰U€U>\›†ÐBƒ‚$u©#ðÔW6(šª :ËP{ø­þÍó’ûÉC&üFÇÊ9®®ŠÀÕü-¹®Újw—IœÃm42»‘¹Ë£~U sëUl<1ªèšbéÚ6µv‘Ë+Gå›\mÛpLùªÄ©-‚O ŒŽ+©¢€9¥ð„qxBËÃñ^0[iàŸÎhÁÜcf#h J=ïŠéh¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ó;Ûi¾(ø—SÒ®d’/h÷Þe·˜Æ÷÷ˆQ™åȉ2F2pÁ}2¼ïá¼ðØøƒÆÚ ̱Ǫ vãPû1`XÛÊÇ ÇŒã•ÈÎ2(¼±°³Ó,ã³°´‚ÒÖ<ì†Äh¹$œ(àd’/¬,õ;9,ïí »µ“áž1"6#*x8 ¬Q@gem7ÂïéšU´’KàíbàÛ·Âñ˲¢|¹1>ÁÎX°çw¦WüHžïx'A¶–95C®Ûêf  xƒ™$9à3ŒòØ8Î z%QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEyÿüÜ/ýÊŸûw^^ÿ7 ÿr§þÝ× PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEsþ.ñuŸƒ´ëKËË;ëϵ]¥œ0ØÄ$‘¤`Å@RÃ9ÚGäŽ+Ÿÿ…§ÿRŽðOÿÙРQ^ÿ Oþ¤/ÿàŸÿ³£þŸýH^9ÿÁ?ÿg@Eyÿü-?ú¼sÿ‚þÎøZõ!xçÿÿýzçÿð´ÿêBñÏþ ÿû:?áiÿÔ…ãŸüÿötÃüuµÔ|/®i>6ðýÄöS¡ÝϪ‡eÃÆz¾B°;·.#PGLâ|Ðõ/^ÛϪÝ]¿‡ü<êöV¢FHÖö‘NÃÞìNw|ÈT⺿ˆ^'ÿ„×ÁwÚ4~ñ”wO¶Ki¦Ñ7äRþ<®FT°ä<‡C¾3·ð§…ôí×Àž9xí"_û1É˾ ‡˜±ÆxÎëWŸÿÂÓÿ© Ç?ø'ÿìèÿ…§ÿRŽðOÿÙРQ^ÿ Oþ¤/ÿàŸÿ³£þŸýH^9ÿÁ?ÿg@Eyÿü-?ú¼sÿ‚þÎøZõ!xçÿÿýzçñüX³þÑÓìï<+â½?í÷qÙÃ5öž"Ìs…‹ýO8Šô (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠóÿÿÉ^øuÿq?ý'Zô óÿÿÉ^øuÿq?ý'Zô (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ªÚ…õ¶—§\ßÞIåÛ[FÒÊøÎ ž;×?sâ ùnô5]>ûMKDC"]¬Y–3o3ñµ›oÌŠyÃq@MŠþ$Ž Z;Í:úÕ&y#‚êUCÌŠÌBíbÃåV#rŒ€qT£ñ­»èƒWm+QŽÒSµgòsre`©³¼‘÷öã<ÐOET¶¼šãO7/§ÝA( ~Ë)ÌÈí•bœöù±ÏQ^qmâýi¼1=ý夓é7×öæX­ DBl%À\Œ99ÏêTW9'‹í-îµ¼–wŠ»ØÑ|˜$p¤+eƒ¾¹*¤ Ã$s]QEQ\>¿ñf¹†|)o³¯Ë¿ÍlA`«•/;.q†ÆPa»pJ†Üñ/‹t [Àú”ÒîœÇiifIîdÇ I'', ‘‘\<ñ ^(Ôoã𮩰-„VvìÓÓxK†.¡‡XØ`SòæDnƒÂ^]&â-wÄrk>)da%üḬ̂‡91§„A–€ÌÝm¥yÿü$_¬Ñ®| cªLŸzòÃWH!“<©(Þ0zHàŠ?á"ø•}þmàK.gû·—úºO xäîH†ó01ÐO× Q@¿…<ÿü·Ž¥©Ï­k·YYµ•Áî,"2Dq‚sµx'Ø(EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPŸÿÍÂÿÜ©ÿ·uèçÿóp¿÷*íÝzQÔ5X4Ù¬"™$f¾¹±ì€ÅòrzaLö¢Ç[Òµ9LV•ÜŠ‚B\,„)èØ¡Èæ¨ø‡Oº¾¼Ð$¶‹zÚêk<ÇpSÊ•sÉç–QÏ5áß_i¶Þ I,ÖÓôé » Ëò;$yrÊO  íCÄÚN—®Yi·qAsyÉ™"(ùYWrÅøíoJ‹Ãž)Ó¼G¦ZÜCsj—rÚÇs5š\+Éu ~¤ f­ozž*ѵ;{nà† ‹i„NŠÑù w²åG–sŒžF®JOê“x?BÒà·KK¨´K‹;‡ G$‘§ÊHÎAu9#>´è~­§jÉ#éÚ…­âFÛ­æY·¡ÚN WÓEù°:…§Û ÛùËæ1ùsŸºAúkžð¶—w©=ýì´3d¶ÿMk=…T’ p2N cƒÒ£½ðÕíõ§áVÞma‚ÛNX|ê-cŒg n9§ò¿ˆtYì§½‡XÓä´·8št¹B‘F`p?Gñ‡Ÿ¡&³§-”­¶;–ºA· làž q«áÛ»ˆn.o4ß=ÊÇo)žÁyroC—µNÃÓÌÇŒU‹k/Áya«ê:Tš¤‘Cwmö}öé:,Ž…þab¨U¶žãò(¦:ý¼zÕÝŒÆ( ·³†ìÝ< )<Š<õ}sÎïÎü×övï"Mwm^tä R>Fãž‹Áç§Æè^º†Þm;TZÖ}ßO‘‘ÁPÁ§Þ‹ß ²(µPñ©á«ÙõDòõ©'´4’6ó!¶*p L»y®>pu àkú1ÒΦ5{§ƒ´Ý ”ò³œc~q×Þ›¡ë1ë–·"ˆâº–d“x#`88èzÿZämôF;ÛmhØj·3G¨‹›‹[é-²~ᢠˆˆò7/S’î­¿ Y_i:¢eÓ<‰ä½ºº†Í$CîÌ‹v‚r;à¹aâ;Q×uM"/5gÓB™]ÔpG;yÚxn V³ñdš¼²ðæ³=´± m¤HÁ]Ò‚¹wÏ·ëÅsš/…üQ£ÝhZ„òØÝËN·Ðà ŽB.™!iBl¡O 8•wAÒ/ídšíб#8\1ôçÖ‡‰ì¾ß£…¥Ýˬ±Ê‹g$i*²°ee2™ƒÁ _ÆžMGO³­›B9$·™.#1¶ÆUÆíÜ’[ çkzU„ñŸu5ªi×ú}à–eÌw‰• º•;‰ÛÂñ‘“Ú¹ë _E©hºž¡a=Ó·–òhdŽY"1¼€2¡ Fwl'¨À4í+Ã×ö~ð=™´XåÓ%ï:þïýTcÁÃ|î:g®h§±Öô­NS†§ew" ¤ ! z6èr9¦Eâ y¥†^ÂIaÝæ¢\¡dÛ÷·xÇ|ô®_DðÖ¡e§øFn-¤±Ó%·ºdeÌR:Gèyù”ž3ÈÍ`&›,óè:æ€wZèwVÒ,fåq ƒp¤ò í9=:šôÝ?UÓµx}6þÖöm†Ki–E é•'žE`Ÿiéw¶Ãrmš/=&둘pN’Ã=@3ÅŸ ¦²Þ UnD~hû/Û<Ÿ´lÚ3æ~CÎqŽqÖ±&Ñ5+QÑeÒ•µ¥¼YHŒSÂ×ÂfÀÝ»!3Àg £þ= i¿Ú_ÛZwØùjûRy[¿»¿8϶j½Ï‹tK]SN°—Q¶WÔ!y­äó#€Ty,_åÆsµ½+PÓ5ëmkQ¸ÓmåKk«Ødwµò žÂщNÀw·;sŒÕ_èºÖ&‰qq¦Ï?‘&¥±¤°o'¹Y#sÊ¡S½20½€s=ý©\]Á Ž&üÉíz¹ÏEÏJiÔ¬BHÆöÛlQ,ò5p‘¶v¹ç…;[¡Áô®oÆz ö¯y¤½ŒK$m!´¿€Å¤Œ!ç¯ú¥\~o­`ÁàÝløWRµ™J]¥õ²Û*È„ÍijPF2Á—,˜ËíwCÄ:+X%øÖ4óg#Krž[08$'€úSÿ·4µ[ZÿjY}¢é–ñ}¡7ʧTg,¨®BÓ׳j:}ôÖš‘oí…»º“Úî-e\,/Þ1ŽíÀ=©ÒxwRÅ·²Ë¥qc{¨ÛÞ+Û5§”¾X_0y£i?!Ôîâ’îK-U®b6™·¾’È%ÄpÌ$òÓÈqó`¾ p3Ž“Ã6Wë ¿¹ÓM„w÷1Ë3£3©fØH*{ÐÅ~«<¶¦âÚô¹¸…m ™Yb•ãÞƒƒ³=8ÏSMѤð¤rßM¡¾Š²)ÝxöF GS™ ~=}ë_ÁkjÑÙF·Iâ+«÷bËþ­ä›k’tt냌qQxwIñü%~¡«Ar=.kkƒ)¶¬Œð±,_1å|o$ý3Èg&§a qÉ-õ²G,fXÙ¥P°9äAÏNE-Ž¡eªZ‹­>òÞî݉[yVD$uä+Í¥ðV»seqo$eJ1[iAeŒ™íÒàJ~ðe¢B€8Æbä`×_á]:{C¨ÝÜÇ©Ç=äªò A­‹±U ¸ põ8cGñFŸ«M-©¸¶†ý.n!†áZVX¥x÷íààìÏN3Ôõ«ë«é¯©¶šš…£_¢îkQ2™@õ)œãð®*ËBÕ…ÊY>öu_O©CÍŒ©ˆÊì8 ¿{) ŒciäçŠO𮩢¶·gV1ŨÏ{ Ô/h-Á‘œ†?(Ÿvi|b€;T×´yZícÕl]¬”µÐ[„&:—çå®*[-SOÔŒ¢ÆúÚèÂÛeL¯°ú6ë^kƒµøFfÓf¶ÕöÓE¹±·/-˜¶‘ž-¸Bd!˜ûÌc©$ó]½ž•5¯ŠÍÒ[¬vÙq[¤¹ˆ\uà7ÓšÞ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Ïþ)ÿÌ•ÿc]þÏ^^ñOþd¯ûìözô (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠóÿŠó%Ø×cÿ³× WŸüSÿ™+þÆ»ýž½€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿÅ¿òW¾ÜOÿIÖ½¼ÿÅ¿òW¾ÜOÿIÖ½€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€+ßß[éšuÍýäž]­¬O4Ï´¨ –8œzWØXk_“ûWU¾»Òü%r¬ô‹f1Ot›™K\¾3±×øˆ*ês•Ü×>6ÿÉ!×íßÿJ#¯@ ?ÿ…%ðóþ…ïü¸ÿã•ß î|6‚çáÞ§&‘8u/§]ÌóXÜ ÃyemÌ®@Q½Np¸Éaè•ÏøŸþô_øE?°ÿí?Ú¾w¶Ýž_ü 9ö +Ѿh?ŸSñV±©k1js^¼76k@l™@ƒ!ÞQvüdc*p¯@Ò¾xEÕ-õ+ 4»¶}ñ;Ï,[±ÚìFGPqÁÁ\‡ácÿÂÇñ§Ø¿áþÓÿAûö'ýIòü¬|ßw;·wé]‡ü]ÿú‘¿òn€=¹ÿø®ßÁövúŽ£m;é(†ââ.m‹Ý@ÿW×-œƒ´mÜsÿñwÿêFÿɺÏ×ágÂ=©ÿkÿ ý™öI~Ùÿ¿êvÿwæû¹éÏ¥lk߬×ÃÖw>ò5íOT—ìÚ}´ƒ™6o- ÈeTR ‚2¡¶ç ÑþiqJ÷þ'“þ}f]áï5(÷¢¡mÁ#„’‘¨=1Ó-‚ÀùCÃvZíαlÚÏ ñ”A ÄS‹}²:¶ÔóIP¬Á\[ רþ´ñMžŽ±ø¯T±Ô/¹ùí-Êcæn­Àn ôDÆÞë@ü žÿ¡SCÿÁt?üMrú·„o<,¾#ð*Î#‹t·žŒ–‚÷s.öK~ê@ ãh9ت éóÃko-ÅıÃH^I$`ªŠI$ðæ€)èzÍŸˆt;-^Á÷ÚÝIJ¦H%sÕ[€Àäž"Ÿ}©Ãas§Á*ÈÍ}pm¢(¼·“-ÏLFÝ3ÉÈ|‚ko„š O‘9I\+©RU¦vSÏb¤{‚ _ñÕ¢].€gÓî/­"Õ—1A Kˆü‰,ª +’ç8ÁÎA6§ Ŧ˜Ë!žêfFm @Ùç9ýâãŽÆ®×èmôZ圶¶W–^§ö$–Aoµ¿–¥HùevU8 qŒ ‹mQ:\qhZ]ý†®º4ñj“ÉBn.J¦ßÞ6®X9@¨Î(Ó¯µ8l.tø%Y¯® ´E 7–òe¹éˆÛ¦y"®×™êš\wz~—‚ô™ô‹¤Ô7I$št–ûOÙn,Yy9`¾gÌa÷º×ÃÂ|= Úi³Ùl ¬à¬‚@NíÌ~ñ-“¿$6s“š×¢¼ßÁ–—qx²Úèi)§C>™1»ŠßL–Õ2«#»3€dÀ27uíéQEQEQEQEQEQEQEQEQEQEQEQEçÿóp¿÷*íÝzyÿüÜ/ýÊŸûw^@¯u -6%–úòÞÖ6mªóʨ ÁlO\)?@}*íÍ#íVÖ¿Ú–_hºA%¼_hMò©äËê*ž¿¦M¨ßøyÒ–+=Kí3d‘D(nzáÙ:sßµsþÔ¤ñ¨%]Vk-Bö¥’Íí&ÅŒ!•|ÐT¦FÂxÆ0s@¤:Ö•q|laÔ줻‡“©“*Ho”ðAÓ²´ßh·öZ.¥}6Ÿc¨_Ú«ÛC<éæ&ÒQ Á ½%G¥sZ-þ ~Í—åÁ‰®ï_PónÔ¸”ŒïÞq³¦6ž½ª÷‡”Ô]ëÖÒF¢ą̂¸0\.U $DÒ;¶;x;Inƒœh|}£]éš>¥kqYꈥy.M§î$›÷˜$x ‘Œç´ÓÙkÚ6£tÖ¶:µ…Õ®ö† ”w Ç$œr9÷¨?á&ÒG‰ŸÃïwj sÞD÷—¨ÎK™#OzÆÐl5k¼pYÞÚèÄÏ$‘ÞI ‘ßp0&LXþØ«·wñøÊæê+IžÖûNŠ×í1:³º<Í– Áˆ>`ÆÐyâ€5í5}7P¸žÞËP´¹žÜâhá™]£>ŒÈük\ñÆ“¢MªÙ¼Ñ>¡a§›ánó¢¾Y"òNìG“òðO9¬Ï hºœº\é#OMO’ÒY„±°ºfØ>@¤™BçxSœqÔÓüW¥j·7zø²Óe»MSA61¼rF¢9WÏ >öSƒæ¨ß8ë@Mޝ§jk)²¾µ¸0³fWò›Ñ°x?Z]?VÓµd‘ôíBÖñ#mŽÖó,[Ðí'¹mgÂ×—­ªÛXF–±]h+aŠB¨3áHàÆqК±ám.î R{ûØ5hf6ÉmþšÖ{ ©$àd œÇ¥u´QEQEQEQEQEQEQEQEQEQEQEyÿÅ?ù’¿ìk±ÿÙëÐ+Ïþ)ÿÌ•ÿc]þÏ^@Q@½÷‹#}3W¸¶´Ô’ÎÒœêqG@ñ+nجùb ]¤ŒgrÏQ¹›Æv-)kTÓ-® €C¼“9òxéÅP ßdêš,:¼)¤ÞÇr©Ù––6â~}à ä·8ãu]ž4MbMfy.¥Yí ²[YK;JÛ–àù˜é޼Ðú·ˆ"Òµ;±]Ý\ÝÅ,±¬0=›‹3²÷Ç~ǾÍ_é¢Ñ¯.-/í¬ÚÖKËiåvÝD€P$pAÂ’z‹‘ÛÛkú¥®¯¹Hm­î,Ú ›9 góLDŸÞ8^:s׊ÈÑü4HÌV¢ ÿc Ÿ`y®÷œpp=èeüH–ú3ê7ºeõ $QÛÉå<“3¨ËvS’ÀrG¾5™uâ¹f¹Ó#¶·ºµuCk{e2FeÇÙ¥”.A+΂­íž¢›kào³é7vÂö'šî+ÈM•§“¼‘•*VíÁ+ó|Üäô«xJoí5+ÝI'¾€½™ã·òÑ‚Àð¬j»‰Pç$±Î}x°|g¤ ;K¶iE½Æžú‘“hýÔ(%Ær\I úU+_MNî[Il/l.£‰fݪxØlfAîEcÛxÕ ×­®¯{mQ Sk 3¾Å99ÃÊÇ8é´cŸ¥éVþ]\ÁbÞh+hú Ç!êrâ"äôë…\ýEnjºœÚlhñiWÚ†C‚< äïuÏ^É>•‹­/¯m­ôÛ+ËõšÚ¦š-V(¥ÎÆ`î¬xü¡±Š©©èöþ1–Öú26Ë$-oªéR2ÛõŽ]˜aŒ!‡$c­Uÿ„S§è– ¨Y´Z\ñ%ÇöúP1c&9|Ï݆Ç# ÔÐÇ…µÛÍvÚöK½:KCäð#1M²*Jè1µØîFìàxÈ­êÉÑ4™ô†¾ŒÝÇ5¬÷R\‚¯‘ÙÜ3n!†æã ¸µ­@ñOþd¯ûìözô óŒ_lþÎðŸöw‘öïøIlþÏöŒù~f$Û¿íÎ3ŽqV?âïÿÔÿ“tèWŸÿÅßÿ©ÿ&èÿ‹¿ÿR7þMРQ^ÿþ¤oü›£þ.ÿýHßù7@Eyÿü]ÿú‘¿ònø»ÿõ#äÝzçÿñwÿêFÿɺ?âïÿÔÿ“tèWŸÿÅßÿ©ÿ&èÿ‹¿ÿR7þMРQ^ÿþ¤oü›£þ߈ôL?ò¿oþèWŸÿÂ[ñþ‰‡þWíÿÂøK~!ÿÑ0ÿÊý¿øP Q^ÿ oÄ?ú&ù_·ÿ ?á-ø‡ÿDÃÿ+öÿá@Eyÿü%¿ÿè˜å~ßü(ÿ„·âýü¯Ûÿ…zçÿð–üCÿ¢aÿ•ûð£þ߈ôL?ò¿oþèWŸÿÂ[ñþ‰‡þWíÿÂøK~!ÿÑ0ÿÊý¿øPq}g¦YÉyw¥¬xß4òÑr@cÀÉ ~5b¼¿\Õ#øðâóRðåö‰1þÓýÍÛ)ÝûœqÑÇ™ï ds^Á@Q@Q@Q@Q@SUÔaÒ4{ÝNá]¡³·’âEŒÅQK2@έc?, I>×ek(Ž9!‚XÔÉr$p‰°+K0Ø## h¤¢¹Ù|cio¥Þ^\Ø_Á-Ä6óÙ²#L­+"¡X«¼†=ûŒUI|{mm-Ú]hº¼ gß2-ì›¶°aÊG  hQ@þ³àŸëž\i°C¦òbŽÚ5‹È|“¾< +d“ÓœAƒË¯Š<]à¯.ËÅzTþ!†i^;MOF Ó1ÜËÛ|¸`ˆìYr 99jè;äŽ>ðçõ{ë|Eðv›k'›¦[ZɽJ Gܶe?{r»*vŒsÒ€,ÂÓÿ© Ç?ø'ÿìê½Æ—â_ˆòǹeý‡áù¥ÓdukËð^3!÷ Àʃ¼Àõ}"ŠŽ!µ·ŠÞÞ(á‚$ q¨UE81RQEQEQEQE^ÛP²¼*-níç-̾T³gkð~éÁÁèp}+ŠƒÄ—ÇÅÚjÁs¨O¦j×é[, Æ’ŸÝm"l«E´—žœg @Ô§Ñü96¥jŠóÚø>ÆT PA¸9 vO° Z¢¼þ÷[Õ´K‹Ø¶Ž¥og¥ü·A–&˜¬ªv(]¦0̧<šg…üO¬êÚý¦Ÿuqþ·ÍÔöˆ”¡TaDBWQÈ]ÛÕ@lçG#½wôWžišž»qáß =λ2ÜkÆ?:ëÈ„y¸y6Æ6cs-¸uÀ ~›­êúÆ¡i£6°ÖªôB¢ßwäJ¨¡C« 8b[ ÕxÀ @¢¼òMoÄÓëš„vîdÓn €"‹E‚d)3Ê]„€°vÚP7"´n5=VËÅŒ/¯.c°žãȱò–µcågl¼yÊûƒƒ·PeQϨ¶ñÎñN¶þN ´-¡ Œ?ÍÀ¬kCÕ¬4O^Þ_ùÖ“i·T;›äýÉ:|ßQŽ”è`†‚<‚)kƒÖõJ)µQm« 6=#IŠö41FÂå›ÌÎýÀƒË ò•9'ž•SPñ³%¶¥©¦ªtö´¿´´M<Ųy%‹]Û˜ØÁÐòhÑêé²Gö¡ijò+2,ó* 2Äyr}+3źN¥¬ii™yöY„ŠÅþö@aÆÒvŸ^zc޵Ék–zž­¬\G­]ÃqiáÁ(±JŒTËÁócbT•ÉçœgÀ£ÃuopÒ,Å+DBÈÃ%CqÓ ƒô ÷©kÌ&Ö5+-Vþ 8“QÕà†Im–1Gö|O„óHŒ1*ÍÛ8â»o ϪM¤ŸíxÝ.cšDS!‹{ ?)q(ŒŽƒ8  š+ŽðͶ—âO[éÖñÄ¢HcQ€X 'êk‰vm;ÂZV¥¢1]bûÃדêÄ{,‚%f‘û—YN<‚H”ìôW“ëVú~•y5މ² âÛOkÿ³¶Ë{µBäŽïpÍÔ“Òº¿ ­¦—­x’ÎÓɶҭ® ƘX¡‘£R꣢õCÝ­u´T_j·ã÷ñs'–>q÷ÿ»õã¥K@ÿ7 ÿr§þÝ× WŸÿÍÂÿÜ©ÿ·uèåí¦j÷W×PÚÛ§ß–y"ýIàUFñˆ‰hï¬iê—ŸñìÆåŸ·ÉÏÍøUXÝÏq£ßÚÙ›á§Ý™ä´ªÒ eÞBîRÀŒ‘ßqX:Æ—«^K¬M‡Zq¬é‹f‰,ЃhÀË‘'Í§Ì ”Ür uW®…¡–‚æÿNÓÉ&fŽI’,ïf%È$}âç¹ ïK'ˆô8m ܺΜ–Ë/’fk¤$þîìãw·Zæµ j â*q5dž“N·™™CK0ó÷/'Œ—Œäàs׃‰žºŽ©Âxe’âkW¢G'dÃ;P̈zzUm3OÔuXd²¶Ó¼Iâ;˳©‰ âPxÎýçîtÆÓ×µz¦¯¦êÛÙj—3ÛœM3+´gÑ€92Ï\Ò5d²Õ,n]#²ÃpŽUF8==ë•ðÖ‹©Á{ %Î’4ôÑ´ù-%˜K ¦mƒä IÙ”.w…9ÇMgKàÍVoh:\6ÑÛÜÁ¢ÜYÜfE$’4ùI̧$gÖ€:_øLl®u -ôÙ¬/!Hásr·ª#Ì“yer‡P3É!xÎk^MoJŠüXI©Ù%áq·k… »sœàƒB=k‰Ô4M[UÕîobÐÆ7‡NŒ+Ëæ0݉î1TéÏ8Ç «ú‡¯§O¼Vjf¾Ôm'·mÊ ¤IoÎsÆÖI1œ8ê(¦þÛÒ´OþÔ²ûj°Smö„ó# mÎsŠ./tØÂ·76:mšâ(D’$1ŒsÐtÁ[«OÃÚ]Æš»ÓÄ |%„á„îJ€wî°Û€oSÅtÚí¥ô^#°Ö-ô¶Õ!ŠÒ{V·I#WFvŒ‡c „*yÎÀ<ЩüU§Yëòé—·V¶¨- ž)æ¸T™^U ã'÷YàœîéÇ7¤Ô£†þæä¶Š-Òv‘®e¸%”ýÕù8bpyÃ\·†µ! -¡&¦%ðü:näš0±É¾bÉó|° €085_ßÞ_\éVó´×všN’ÒTŒW1pW'i#p#8Ï õuíô³©®­bÚzœ±p†!Î>þqúÕ+_h7šçöE¾§k%ËAñ ̸0Ùb@=ëš@Ô£º·Ö†Ÿª]M¢.§³¿–ÐI6 hƒ ˆˆÃ.åûÄ·¨â¶ìãÔÅçR}â+kë oÞBM³Ç$Ì|Àœ‰ÜÝÎsë@ºüZV“y¨Î®ÐÚ@óȨbª¥ˆ gÖ«Ëâ "ØD.õ;;W•Ö;‰Ñ¼Ü‚®¥UÖa¾Ö<ª[‹†úîÂx–Ù¤RC²0 ¸½Hç8¬‹¿Þ\\k25sqáØ¬!%—æ÷§^Ï'ƒëÅt:î»aáÍ4_ê2ˆà3EK(åÜ(?19>€Ú¨Ÿi1ë g=õ”6ÆÖ ˆ.ÞéNeyT*çƒþ«<Þܳ[Ó¯î¼ok kØ^Îf‡z‚æ)c‘”@É@ÉÆ{Õ GD»Õ¯µÛ×ÒÊÝ;8RvŒ¸“tå£8bß'8÷â€:iµ}6ßP‹O›P´Šöa˜­žeY²¤äþ-åí¦j÷W×PÚÛ§ß–y"ýIàW¯…5u¾º†í5Y­ï§¶¸/i%˜D1¤c˜ ´d‚„ŒtÁÍu~&±»žãG¿µ³7ÃO»3ÉhU¤7@˼…Ü¥#¿ â€.ŸèA­TëZp7``n“÷Ã8ù9ù¹ãŠ•µ-5EÒÛR³ƒ ‹C:ù¤c?s9éÏJâ|_§ø›]Óu+kM6îÞ­8¤6ñ5 >q/•œ±P,õ'æ‘}ôÍf/HÚm½õ­½Ôþeì³InöÏû­¾b ù«'1Âðh©µÕôÛë©ílõ K‹‹s‰¢†ewŒÿ´Èüh¼ÕôÝ:h!¾Ô--e¸;aIæTi¢‚y?Jã<á½CM¹Ò“Q‡Tivn’»Ú}™²6Ï-D¤¡¾p:s“V!ÏkàMgÈðÍÀ•丛÷’G©¬h ›oº®¡›sFÇr‡$«Ê|/ø•­]xƒÄ© —ú÷ˆ.k¥”‹HÞϹ‹**À\’±ÈÀ¯_ðg€aÐ]õjXõoÝ¿›u©J€”b¥vC‘ò RW€2;…^Mý›4­ÙuMsR¹Ÿy*öª(\ °rNsÎ{Ž8çÖ<= ÚxkFƒK²–îH!EUk«‡™¸P¼n8Q…*€£œ@”QEQEQETsÏ ­¼·Ç !y$‘‚ª($“Àsšóø|kâo!›Àš5¢éªì£VÖÙ£Šr¬T¬Q'ÎAà‡82  OŠšgö¿ÂÿÛyÞVËCs»nìù$K·vc=³žzWÍ ´/x‹\’ÃÃZ¥ö—nvµýݼÏFƒ8-´ÍËm^üôˆ÷ûûŠúžsay¤µº‰á™7^ ÈÀ†Œ‚zUêÖ~þÍð6³¢aßM»ì÷k(–ÛRmVq'HçŒ2ÁÆUh¸ðdž4¿èpéDU¼|³7/+ž®ç»È Š( Š+Ÿñ_Œt¿ÙÛËçÏqu(†ÖÊÑ<Éî0‰‘œdgžàu ‚ŠóÿµüX¾ÿI¶Òü)¥ÂÿvÎþâiæÏÈrFF:ä>×ñbÇý&çK𦩠}ë; ‰ šLð6¼¿ Á99ê’(Ð(®ž1Òüagq-‡ŸŬ¦«+´òç·pHæN3ƒŽ{Ô: (¢Š š“ñ¾K²[ÂæCp¶è$ÞA·c9Á#>榃N±µ[Ù[ÂKòâUÄk©Àû£qÀè2}jÍBÛCÒ,ì§²µÒ¬`µ¸MVè©.Få#ƒšž; 8nÄVG0ˆ@$XÀa9 ž»A'§5Éê¿á]RãEðÖ•wâ-bÝöO ©ÁnÝq,íò! >ÏÌ…N Sÿ„·âýü¯Ûÿ…zbhþÓô™åº6öÓ_½ÍÄÂì۪ʫ,¯&ÍÜœ øëÎ:•¥|C…µK}ĺU߇u‹‡Ù7DIÃuÄS¯Èä™3…5ÚP9t6}5tÙ´ûI,B-«Â¦ £ F0;qQÜhZEÝ„V:UŒÖpãË·’Ý4ÇL)¡EgÍ è×6÷3é6Ü[€°JöÈÍ’21íKý‡¤ Iõ/ì«·¸!®¾Îžk0Alg§jýKNÑ´½ H4Í6ÎÈJs ¶cÞ}NÐ3Vg‚+›y-î"Ia•JIŠ]HÁ#µIER»ÑôËùmå½Ó¬îd·9æ\Ä}T‘ÇAÒ±uŸkZŠòi,x˜‘` ÑÁ¶ ÷p„‘·8ÈÏ5ÓÑ@A-¤í+Mk4^L…ã¼|ü‡=W“ÇNMOES›HÓn-ç‚}:ÒXn3Fð«,¤`F¨ç°•-¦j–¶6°ZÛ§ÝŠÂ"ýàTôPe—†ô-6õ¯l4]:Öí <¨Žs×,y©í´6Êæâæ×O´‚âäæyb…U¥>¬@Ë~5rŠ£k¢iVV³ÚÚi–Vöó’fŠ+uD“<À ûÒãivúxÓáÓlã²0¶HGœç;@ÇPÖ®Ñ@F›b1‹+n&7÷Kħ9~Ÿ{“Ï^jÕPŸÿÍÂÿÜ©ÿ·uèçÿóp¿÷*íÝzdë~$Òü<ö ©ÝGn·³˜#y$TU!Ë1b0¿.3Ï,£½Ckâ­:mf÷LžæÖÞxnVÞÝ^áC\î†9rŠpOúÌ`g¦{â›âk[É_F¼³³’ñ¬/ÅÄDè®Èa–?—{*ä䎬mC÷·1øžhìíÚ…œöä²nd-ùÎxÚÉ'_N:Œ€uk«é¯©¶šš…£_¢îkQ2™@õ)œãð¤Ô53HXÛRÔm,–S¶3s:Æú Äf¸­'Õ®± 7«ªË œ×ÑÜDö‚Ü—g Ÿ—Ïݵö‘È÷Æ+wÄöúÍÅݬvÎlšRsj-Ì›ÎÝ¡¼ðTFFìíä(Ú·Š†™¨\Z­ ˜E“‡ãwÚ. >‡îãw¾qÇZÓµ¿Ñã¿—J´»°[Å-,–‘H‚@Xîf(9䜓ŽIÍpv¾×SH±†k3çG¦h¶ò2Ior^QœóµyÏ~Ù5~ÇAÕc¼Ó¬dÓ<µ²Õî5Õ<ØÊÊŽe ýäH²À<ž(²MOO‘áD¾¶gœ9…DÊLo<í=qÓ½9µ°K÷½·[92\TFÁÈ Cg$ŒzäWšjþñ\ë3éöèd·¿²š£)sæ†äñ´ÍœgËãµv~"ÐÍ×…`Òl­–X㸲S•ñ3gs·ýî:Óañ‡pm„Ö)ºbºFóXu ƒóè+›“Ã7rxF÷Oki®uãy$e“BoÄ»8?ºÇ^1ŒñF£á›¹_ÄÒÛØ§›{g=»@]b峞0UúàñÇZèÿ·l­ì%½Ô¯,, K‰ ó^íve]”Ç7ËÊõ#œSäñ‹¶±I«Ø$—€5²µÊ8= üÀöÅrÒèwðéJM†¢obÕïníäÓæ·IJK)VÄ­°‚È9#=3P?ÄÑÜXÝÅepš¼°ÛÇ{4onläUbH‘XïncO¥uðX[YµÖ§}§ÙD.d·W{ÄØJ¹P7Ür½AÈç5Ö»¤XȱÝê¶6ò8VU–á°bB èJœzàúWm¢êÚV¨š›hí¨ ›SO³$±Q=Ϙ’ ìF9Ž"£Ó¼¨Úi·ö×±K#øj-:2®¥|Àg-Ï;FøÆNãÓ€ÖïYÒì/ ³¼Ô¬íî§À†§Ty2p6©9<ñÅ.¡¬išBÆÚ–£id²±›™Ö0çÐn#5ÉÞišÔÆ—gz—¯¬73mÚÖECó U˜ ø1ŽIÖ§‰íõ›‹»Xì#œÙ42¤æÔ[™7»Cy਌ÙÚ ÈPÍæ¯¦iÂ3}¨ÚZ‰²yó*n€HÉäe—þú´ZêúmõÔö¶z…¥ÅŹÄÑC2»ÆÚä~5ÊhÞÔ¢‹Âò.];CšÖy «'e·QŒNNFGy_ÁÞÔ4Û)5uA&—hÖé+½§Ù›!ClòÔJA*ç§94ßÑEQEQEQEQEQEQEQEQEçÿÿæJÿ±®Çÿg¯@¯?ø§ÿ2Wýv?û=zQEQEQEQEQEQEQEyÿÅ?ù’¿ìk±ÿÙëÐ+Ïþ)ÿÌ•ÿc]þÏ^@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@âßù+ß¿î'ÿ¤ë^^âßù+ß¿î'ÿ¤ë^@Q@Q@Q@Q@Q@Q@Q@w Á©ñ¯Å×—ÑG=Æoema#(ͼrÄîá}ËópHè•ç~%ŠûÁ,¹ñ½¼—z-ݺ¦»ioùÁ‰XGp›˜ B°¹b%{M\ÒüC§%þ‘í«`o…ó´ÖU°FTàŒò(B¼ïãDÃàuäŠ1ªh÷\Ø\• “ÎŒ3ÁuSp28ô ç†ÖÞ[‹‰c†¼’HÁU ’Ià9Íyž«¨Â×ÔG‡ôS¿ÂÖwcûjýãýÝÞÂŽ°@á²rAÜÃHbêQEQEQEQEyßÄhW]ñ?ƒü!xdþÉÕn.'¼H¤diE¼aÖ2Aû…ŽHëÀ ‚3^‰\?Ä-/TIô_èv_Ú–,²}„¾>Ñ©²P¸2_dž8SÒh#Ò Òô3'™%¬_½pÙF%ßiÀùw3c#8Æy®?⯃¼KãýGJÐì|‹= ô««Ù[t¹ØP Û• ÈVß‚A€3üñûBÖ¼«?Åý‘|Ø_;%­¤o”gwXòK6U@åëcáÑ·ñ'Š'òÖò<¤ûUÜ ¼máÀb[–+ÐüCñGKñ/…ì,¼)­}ŸRÖµ }4¶v\؉H/'–yl—rœe¸|Šçü7ðãSÔd× ÚwŽ|5¨èöúšë60C4bM·Q«G÷rnÀ#z‚3Áaê+VÛVÓo.ä´µÔ-g¹‰CÉ S+:)èJƒG5ÇøoBÔb¸ðÄzŽ’Ñ&¦\YI,¯«H|€¬›Xœ0I:€zä ŒÉáï ßéVþQe2XXO Ï̸Gp„ƒÈ,¤ñž”ÓÛøƒE»ŽêKm^Âd´R×-Ê0„ ’\ƒòŽ_JT×´y šxõkŠXå‘n¬lÇ ¬sÁ$€êMy®©¥ø„iZž¥ªÃt¢? j÷Sl±¤¬±°X–/›gÊøÞIÙæÇ‰,u<ßK¢¥œQG§Ø¥´’¡[–ûl$ci8Œc¶Î~Q@„5ÝéϨVÄØÆv½È¸O)O¡là~tù521u)u4°`ºiÔDAèwç­pº—‡õÝKVmz+;»-—ÑL,c’ÜÎÁ!x̃vø·åÆ?u:ƒŠ½ygi¤]Åcpmu9¯f³º’ßÎ&D‘w …b3îÀ=ÛœÐM¡ë1ë–·"ˆâº–d“x#`88èzÿZ«áïišþ‘ox·v‘\5¤wW¢å]­•”7ÏЀ3ÔQø7OºÓ´«´»²M6¡spVÚ!eû¤Œàô®GKÐ|I‡ôKX48lo´}6hüÉ¥‰ãžWh@‰ ·ÌÛ°2£¯Zï¡ñ‹q§Ë¨C«ØKe Ä·)rö˜£­#ø‹DNQ}gO[[lw-t‚'>³‚x=ûWžÕ¦½Ö.¯ìu‹ˆç†ÄÂLÖir%†I[r„Ä.Sï‘ÆN0]Å2Ϧj·Býå·K¨ v¿c!$t(Ì$ÅS °ŽØÏ"€;»Í[MÓàŠ{ÝBÒÚ)˜,RM2¢¹=$òOµC¡êÃYÐm5C€\Gæ/»gã\ݶ…u¤I¡Ï—sok§Mfm¥–,%ÙÊ¡B§oAŒ3RYøsPo„£Ã¯vºƒi­oåïÊ+#iaÛ¶Gc@¶úLJçIõKmGL‘We¼×qÏæùœï9À'«qÖ®YjZ¿Ú,/-îáÜWÌ‚U‘r:ŒƒŒ× ¨h:¦¹=ÕÙÐþÁƒN€ÙÉ,LeX®–Gc±ŠíTÈ9<ð8¨Ò¬.-|C¯\ÉÈ.å…â`ÃçÄJ¬p:r¸çÒ€(iéw¶Ãrmš/=&둘pN’Ã=@3ÆÂkú3é©&­`Öv½Ð¹CŸBùÀ?r³h𕯍è²éNÊÚÒÞ,$F)áká3`nÝ™È`3Œ Ô:ç†uyuûJÊ9Ö(õ®Õ-Z$¸¶1A()¸>ø‚(®}nÌ=¼«wbÖÛKrnÒ€6å€èˆ$¶p¸µfßR°»·–âÚöÚh!b²IªÊ„ H8w¯>¼ðž§.•:ZYÞ—ŸLÕ£d¼–ÜH'¸òŠ)òðƒqVYsÈßœwÇnµÍi~ñŒ ð™4ë4ýLêë$e™až>Q`ãýYìj¸ðö¿swªÏ-½ë‹“¥7¯j²1†è¼™áFÔÁç$ôÉè=jL¨ËwnUæh‰E$2y`UFÓéQ®¯¦¾¦Újj~‹¹­DÊeÔ¦s¹´f+› ì·0[k÷ƒÞyÑì0Èó8ÀÝ»#Í‚CŒÕK jVúˆ·¾‡U¸†F{ØåŠKE·}ìädíî*ûHä{â€;‹ gKÕ^dÓµ+;Ç„âU·d1Ÿö¶“އ¯¥^®KÁöZ¶Ÿ4¶³[Þ[éÛǬWïËAUhIÌavãyÝšëh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(Îþ-Ï ­¿ƒî.%Ž"ñE“É$ŒQ@rI'€ç5ÒÂwàÿúô?üÃÿÅV¦¥¤éºÍºÛêš}¥ô áÖ;¨VU ‚23‚F}Íeÿ àÿú4?üCÿÄÐÿ ߃ÿèkÐÿðcÿGü'~ÿ¡¯CÿÁŒ?üUð‚x?þ…MÿÐÿñ4 àÿú4?üCÿÄÐÿ ߃ÿèkÐÿðcÿGü'~ÿ¡¯CÿÁŒ?üUð‚x?þ…MÿÐÿñ4 àÿú4?üCÿÄÐÿ ߃ÿèkÐÿðcÿGü'~ÿ¡¯CÿÁŒ?üUð‚x?þ…MÿÐÿñ4 àÿú4?üCÿÄÐÿ ߃ÿèkÐÿðcÿGü'~ÿ¡¯CÿÁŒ?üUð‚x?þ…MÿÐÿñ4 àÿú4?üCÿÄÐÿ ߃ÿèkÐÿðcÿGü'~ÿ¡¯CÿÁŒ?üUð‚x?þ…MÿÐÿñ4 àÿú4?üCÿÄÐÿ ߃ÿèkÐÿðcÿGü'~ÿ¡¯CÿÁŒ?üUð‚x?þ…MÿÐÿñ4 àÿú4?üCÿÄÐÿ ߃ÿèkÐÿðcÿGü'~ÿ¡¯CÿÁŒ?üUð‚x?þ…MÿÐÿñ4 àÿú4?üCÿÄÐñ ĺ³qàË}/[Óo§_X»Gkt’°\¸É IÆH÷ꕇ‚ü+kqÅ¿†´hg‰ÃÇ$v+#A Aç5¹@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@âßù+ß¿î'ÿ¤ë^^âßù+ß¿î'ÿ¤ë^@Q@Q@Q@Q@Q@Q@Q@qúÏÂÏëú‹ßê:tù.ðÉ$;É$–a(f$œ±äú×aEpp|ø}mqéáØËÆáÔIs3© ç•g!‡±õÜA6¶ñ[ÛÅ0D#Ž5 ¨ `Æ*J(¢²KˆÚE² 6ì.9Pr0xâ€5¨¬ÝO_Ó´‹›kk¹e*ï PÛÉ3ÈnìRxÜ¿ä‚/hÓÞÛZ[Ý<óÜCÄk H NJ«’ªB®T‚N1ß³EbYø»B¾iD7à,PµÁ’XÞ4x—†‘€WAÆYI#ži‹´cdnÌ·IuØÎ¯+0%DhSt™Ÿ”  ÊãõŸ†Ú©¨¾§g%ö‡©É‘5îpm¤™I,Áð ¶X‚I‰QϨþ/ÑV yVây¾Ð¤pZM,€!Úû‘P²mcƒ¸ *Ìúþo©Ç§3Î÷R;aµ–PÉ ]•H@H<± r_ð«?ê}ñÏþ?û è<7འÂÞdºu¦ëé²n/îËs;n/!çæ*…Ï8ÐQ@VG‰5Øü9¤‹ù-åMÄ0l‰ï$TÏʬx N1Éu"€5ê½õ…ž§g%ý¤v²c|3Æ$FÁeOøU?øH´±äÒ\<+el·Wh^6Ž& CeøŒg‚:Ô~-ÑoîÖÚÞêC#NöÀ½´¨žjgt{ÙBîOËœœdP5ÿ —N·ýÖ“â_é+þ®ÆÃUe†/]¡ƒNXäžI£þ.qû­[ľ+Õì[ýeþªÍ ¾›‚…<0Á]T^&Ò&Õ³cºcqæ4 ù.#iÈ$Û°¸åAÈÁãŠRÖÿ³uûIš줲ººži8)å°sœ‰œú”¥cag¦YÇgai¥¬yÙ ˆÑrI8QÀÉ$þ5b°âñ~‡-Õмxã¶Ò¬ÖòFà9ÂŒ¡˜1ápãÀÍ[ÒµÝ?Z7Ægw¶qé$/ÆÄ•À àƒŒPQ@Q@^«ðòÕ.5¯ j·~Ö.|óZ$ Ó2Àß# àŒ|ÎXäÕ?øD¾!ÿÑOÿÊ¿ø× Q@^•ðòÕ-õ¯ê·~"Ö-ß|]íÓ1@¿"dœüÈ`×iEQEQEQEQEQEQEQEQEQEçÿóp¿÷*íÝzyÿüÜ/ýÊŸûw^@o.ͬÖQ ûDþQó&GÈÍòŒ|íòýÑŽ2{Tv:Þ•©Êb°Ôì®äT‚ád!OFÀ=G5S]°¹¼Ô4 mãÞ–šŸ1ÜÄò&Ló׿uóX~ðõö›màÔ’Íam?N’ °¬¿#²G‘Áç,¤ñ‘‘šÞÿ„›I&½ÜI¨,1Ì#yÞ_ £9,dŒte=ê/x§Nñ™kq ͪ]ËkÌÖip¯$Ô0=ú)†ÞöÛÇR_-Œ³YÝØClgÐZ7•ŽðÌH1´7CœW%'‚uI¼¡ip[¥¥ÔZ%ÅÇP#’HÓå$g ºœ‘ŸZïm¯ô~Òâ+[»J؃ ë‰2r0U€Èäv5Þ© ›¿ì«Ûý7í+¶_²M2o~pÛ ÏCŽ1žÕám.î R{ûØ5hf6ÉmþšÖ{ ©$àd œÇ¥GýŸªÛøÁ¥Ó¬ï!²¹ºóoŒïnö²¯—·z ™UþUÀ^h¦—TÓà…&šúÖ8ž&æP­Œ³‚O*ž€ª|M g:æšeò¾×ŸÜ<ýïnµÁØèW÷ú?ŠìcE›û>ÂçCÒ”8ù•ƒ62x4žzÄ ÍKÂòM{¬=¾ Ž.Ÿ6 ¸2üx)Éãò  ÉîÓQ·[¨-íîU•L’¤d–÷cÛ·ZƼ²×í/nn,tï´Ïu¢Ch’3ÆR)ã2·ï0$0”79Î5‹wá¿^®·#Ø]]}­tÍ‘êZ«Ja¹g0‡ B:䑯O@è1ëšDÚlš”z­‹ØFH{¥¸C‘×/œΧ²¾´Ô­RêÆê «wÎÙ :6àó\tÚ=åúëW÷:5ôk¸¶’ Kyà ðà‰²XÇ»8à±ÈAŸJÚðôšäVvðê¶’;É$ŧvˆcd’{~$~³‡E±ÓỽŽ[)Zxoƒ©œJÛ·¹%J±mïTƒ»¥YðÞ¿ˆôŸ¶Ä#%xdL%MÊpJ¸á”ðAÀàôŠÍÕübš6¿o§Ü.œbšx`j*.³! ¬ Ûʆa“»8ÉÆ^77ú:%ªéúÆ´q¹®ÃÚ©$“Áãéì¸ýj¤¾¶Ô%’êKFÑ.® Ô&²ß:3]Ä+þ­AŠñÇ­dj6¿ŸFñ3XCaos§Z]Úúâiu-Bþùd·šÙ"˜Æåp¥Xð1óÅkYéæßL77sß®Ò%ÈM̧±Øª:qÒ€9ØüwúÅÆŸŽý·–öÖòyÜ\,›·¸ãž\¼s£‘ž&_¢x¶ uÓ³q4Åö}EeYQŸ2C´P󓃀qš]/ÀZF“.‰,]»èé2ÀÒȘdÎæ“ŽXn|¾Þµ-¿ƒ­-¯í.úøÅiy-쥣òÖIº&æ½sË=qÅr^ñMä3év¯%Æ£¨_h[ÛI9ÃÈZ2Vc£w6 8àWYoâ‰.É<’ÄXæI"Æät`êFàAÁ‚¬ë_Ú[^ ·½½¸¸þÐþÑi&dËKös »p1Ï··ŠžD±7"6¡.pVmË«»ihܬTp̼TÑx”ÍáKÍ},$’(„ÏQ¶æž4f ÃŽ7Ü:ðGZ¡âOHþÔ4½2‰§ÔnÌÂo5ì²3‡órH;Q€ ¶qîG@šdVú4ze¤’ÚÃ+O £U dphÃÅÏsŸ<°éÏoyxm ö‡ÚcŠ\‹Éa³à•ëž!Oß^K§Å¦hÑÜ5úÝËKy婊 ’ˆ€q‘êHƒ]ðœÃú•“^ê–«4eïe’(Ú]»%;B`8U,N>£¡·Ð,­n´É ßÓmÎÁ|¶òúñœ)qϯà•¡xº}bçM󴯲Zêv¯qi!¸ÿ&ÝÊê ÷²fÈã¥ah7»Ò¼£]k¶243i~tWBçÍšwŽ0Ä:0\AÜÙïƒ]m‡†l´åÒniP<o`w+¶'å1YvŸt»{tû‹½BúÊ G´‚ ©¬H뵈*ªwÜ“Œ¸OZñ¥öIl/-?³5ŸO™MµÙ•^).ÑnÚ¤ °Æ0ÝH&µ¼S©jú}敼†îüÃ2O)Œ:ù¸\„rS9?( ÂÚºÌo5BöâV·ÍÅæõX%¢ ¨7N2sÉé-cGXŠØ«‹Y­gOo³z>Ö\áÕ”å]‡ õ `xSÒõϼ¶FçNƒR¶ŠIìƒÉ¸ÄhT_½‘’H«Ïã#Š#ÐÚ=1¦žIabÔƒÌQœy±ÌjBAldsZ3øbÎâ N)&¸?Ú7\LÛ”Ѭj6ü¼"\ýON1ZßÁÖ–×ö— }|b´¼–ö RÑùk$‚@Ýs޹剸â€jz¾«à½?PÔâ·k¹­#•Z9³ç€å†ÅIì2­c‰QIè´ÆmÚlwqæln¸rƒìçåà6>}ÏWQ¡hÉ éÉa åÌöÑa`Iö~åÀE* ?ÚÉ÷¬xþh±y;Zë÷Z©ÕW÷ƒ™0‡õc ×ä^x jþ1M_·ÓîN1M<05Y…VmåC0ÉÝœdã¥Ð¼PúÖ±ygäYÀ¶Ï"Íîn—kíáØ6«c î<ëKwàëK»Ë‰õôQ\^C}-¼mGš"…I% c÷k‘»€jÍ¿‡-j=RãR¾¼–‘-ÒsØC‘¸ ˆ¬zó  z׉ïtÝNþÒÓIŽé,tôÔ&‘î¼¼©iU[2@9äŒs¾5q$÷0ižnkq µÅÙŸlŠÒ9Xöʾbä–®ÅlÝè6·—ZÄ’LþÅle Fjd ¯{÷­×#Ç®qðMŸ"òùmH¦žÉ]<™äˆ(Wo—v~DÈVí€DÔµ‹¿ø†Öê+caiv±Âë1Þ€Á…Û匃¸±%² Ç TµoK¥\êÞf³Ó®¡´7ÞüÉ%Ž6\¸P ƒq,0FzVõ¾Œ–šÝæ§ åʋͭ=¯Èbg ¨îîj¨á±ÇJ‚çÃ7I©‰à5ýÌwlêà4RÆ‘ª2q)O9ç=Ž(/Ç&‡¨^¥½œóØÜE Ÿe¾[bM¸Ì!ã¸ìÈÚxïV×ÅW×"ÂßN°°¾¾º†[ŸÜj9¶X‘‚äL#ËX6Žù#¦º5Òéò[¶¿ª<ÌáÅÙ €ÇÕMg'‚m Hž×RÔm¯Q¦f½‰£óeóX4B˜%Tð£ã‘ŒKjÏ«¤s¶&›§»Á$˜û?™q2;ã‘•ãv:…ëÀ«ú§ŽàÓŒêa¶Qý tûyn®ÄHëùœ©Øªw/F%†1Wãðn“­Åª$¿f¸ÓSLx‹äyKæ`äŒî>cd’{~$~³‡E±ÓỽŽ[)Zxoƒ©œJÛ·¹%J±mïTƒ»¥gXxâ]d[A¤iÖ÷w®'i”^ ,LªJÊïÜ]vð23¸­/]O{à­"ææIdš[pÎÓ6ç'ÜúÓäðטֳcRÖé$l!#£Yy{1•R0 Œpzæö¥A¡èÖš]«JðZÆ#F•·1Ô÷4Æø·þJ÷ïû‰ÿé:× WŸø·þJ÷ïû‰ÿé:× PEPEPEPEPEPEPEPEPEPO‰tË[D{[Fˆ\,ÐOšÅQš)R@¤€Hf3ƒŒô5Ëø’Î][Å:—™måÔXÕ­!”É‹Tq(9Â»ÐÆ "VãÓ¾¢€<÷BÒõ]QZ6ûipx†òìʼâRêRnÜrÃ;·tãozµ¥ø2ãOÕKw6Q^ÉyϪ܆BÎÎÙÿÕd#9댚î( GÄ'Q_h¦Ek,ëa|Lw24j˾Ø}åV äƒ÷OLwÈ_øJãIžá®®"•gÓ£¶v‹ ùžlòH@#…ýðœñÍu´PŸ·‚5mKJ¶Òµ+‹(mì4Étûi­‹;JYUŽ¥@P  -’zŒUý_C×µè,f¼ŠÆ Í>ãÍŠ;]FxÖpcdlȈ¯ù²0¦A®ÆŠà®¼¨64°°³¶¿&fûRë7^lä|ÂM…¥•m ‘ZZ†ƒ©Ï®XÞ[¥²É'¿KÙa–DFË£BªR@Fà77utPEPY>%Ó.5mím!p³A<~kFh¥I’ ˜Î3ÐÖµÀø’Î][Å:—™måÔXÕ­!”É‹Tq(9Â»ÐÆ "VãÒ= KÕuEhÛìi¥Áâ˳(vó‰K©HM»qË îÝÓ½ëШ KðeÆŸ« –(îl¢½’ò)ŸU¹ …œ³ÿªÈ,Fr3×5£â¯ Íâ9Ð$ñÃöuÝ£1É`ò˜Š:<³žGo碀8-cDÕ.>Ó¯ëU…ŲÚù ³;Aû™¼ÒdvU 18èvõËUßÜÍ©_x‡Usjñ]^F#’ÒC$/²S±ÈÀÖ\áÕ”å]‡ õªóøbÎâ N)&¸?Ú7\LÛ”Ѭj6ü¼"\ýON0‰gñÊó]ŠÅ—‘5ãÙFVýZçz–š eP• Äò —Å2êòx§B°±ÝÒyÙ£-¯˜é³ŒhĨݜt9äqεŸ‡WO¾im5;ø­W˜Ø‡{’ÌA)¼ÄœÆOJ»>™ Æ­g¨»H&´IR5m"M¹ÏþŽ}h˜Ó¼QxtÏÁa¥5ÌÚŽŸ-×úEóËÈgØYÉó1œu×"”Þ6Õu 6¡¦C¦E8»³ËMCÌ’1$è­ÊbýÛ`í#œdr£=5…ìôñ¦&¹Îg-œ$²ä£˜É'¼<µÆ0:ñUÁV×éï5MFîêtŠ1s)‰^!žbmÙRC€rÁºsÅijš¤úG…ïµk›XÚ{;9.^æ%ID-´9PqÆ3·ð¬¶ñM幞Ý:ÒÒàZ-ä>mþ"1î Þd…>B¥†psÁ5wÄ:mÝßõm2 $¼¼›NžÚRŠÒ»FÊ3€ª $véTá´š"nµ F{°¬3Jñ–¶8‘U>L˜K†'$â€3ÇÄXßJ71Á§™üØË1ÔA²Œùb@æà!ùH*T|Çyü_2ëv:a¶Ó£{ˆb”¼ÚŽÁ.òA[Ý‘1ÏUê=jÔ^6ëxÖúî«ÅåÏÚgœY¼µhÊíÂ/x=08¨‚m>Ãi§.£¨.™n#b ŽBŒ%7‚Híe š¹Gñ‘Åèm˜ÓO$°À±jAæ¨Î<Ø‚f5! ¶29­í6Ê[î×rÝ<×MºB~Ef%QA'FàOÅdÛø:ÒÚþÒá/¯ŒV—’ÞÁjZ?-dH¢naû×<±#×P=aâ?Ïá¿]˜,ãR™R×EE›iæÄ?»$®~Pq´ N/XüE´½Öá² b"šíì“eúµÀ‘K ÍÜ„,¤œò P iGàØaÒlôøµmEÂe–ÆAä—¶Â2\dž]¬Ãç yëVl|84Û¿2×UÔÔÊóÆa.Ä–?sx‰l'Ú€0ôßkœZQ‹Ã£êÖmuhPù@P¥„„G•ûãi³žBö»‹®¯†„ºf”’˪ÙÍu‹‹Ÿ)`òü°UˆFÏ2c u±ÈÑÓü3e¦®Œ!–ῲmÒ ìä`€–Àäþízc©â±§ð„±êš6—¶Öšu•Ü_k‰ãó¡Úe!²ÿ„ŽÇÍÅ:®±âY|›H¿³ Ï Mûؤó'GÀwÑíÆà0 Ž¤VŸ…ãsw¥¤`Ô¦Ó¾Ð.w>ä‘£³`ùI\}ì‚zÍeÛüSµ¸²¸ºK{)û>{ûx ÔVYH7ì™Bþéˆÿ{ ò0t4_0ygÔç»Ø5[»Ô±i %¦Ç!ÀÝ÷YNÝØÏ%sWSÁЮ‘u¤_S}2kI,ÒÕž"°FË·Û7s6('U¿Öîµý+«X­,¤Y®¦ŽRTm¨åÊF2T1;2Uãš•¼yso¥¶£w¢ˆ`ŸLŸR±ësJ± }’ Ÿ»b¤7޼ä`ôÓéוì…ËÚE,H™Yd pÇ?t~µˆ¾ÓþÅ-œ·ÚŒöæÆ]>Þ9dB-!‘B° ’p÷:g ŸÄzÜWšuŒz ³Þ_C=Â#_•XÒ?+ï·–pO™Œ@ rA$&…âéõ‹7ÎÒ¾Ék©Ú½Å¤†à;ü›w+¨\/ÞÈ!› sŽ•¶úT«Yê%äó­-å·AJÈc,OÏî—÷?…K Ùiˤ,2Ü0Ò x ÞÀîV lOÊ:b€(x³Æ á_ßLšs[¤FimEaÀ'"(ÊŸ0€3ËžƒšÓñ°Ú&Œoâµ7oçA B$Ù¸Ë*F9 ôߟ÷Z§­øB×[–ýÞúúÔj‚Îém™–1»²ÞÝ<ƒZz–—©`–s¼‹M À¡îŠE‘zƒÆPgÛ=(oÝ[[_‹›]6ÖîÆá!—íZ—•oµÐ:°”ÇžøÆÎ¾ÜÕk_Üê±iCHÒaºžþ;¶!¯BÅ[ȱ·Î¨Û”–8`9ãŒ;ß Ú]êm©-Ýݽá¸K„–"‡c,F.+ cœƒíŠv•á[-&âÖx®.å’Ûí{ZgV,n%Yd-€2w(DZ9ÏZ££xÊMJK .tϱÙj’][JÓï|&ÝÁÐ.†È!› sƒÅeÙüP¶¼…¦ŽÒÞq%”·–ÐÙß,ó€6Éc÷lAÎn„FKeá{ô˜ãyÝtËw·„HTïW þ9?(銎Ëà §[sUKD‹Ê·ƒtD[¯m§ËÜpòÔŒn¦°Ó¦·²Ó/%¿¿ûbËSób_Ý<…™ü°A+·#¯=*Ìž+•4YîÞ >ÚæÖí­.R÷Pò`€ÎD»AHùAùº ¡¨ø.Ss§Io}5Ãê«wy|ÏJm¥XªœƒNsÈ#5¦<h–¶Éõê][ݽà½Ìm+ÊêÊÌÁ§*Ä`(cÅR±ñ¬ºÍ¾žº>ÍåÒO#¤—›a‰a“Ês檶à\ü¸^G"%ºÛ[Ëoam¨È÷ ,wºˆ‚ü—Ø”¡-’FÑ·$g8ÅoÇá›(’ÙV[Œ[ê3j)–É!°<}ßÞ¶^>µßÂË9º´¿¾²¼ó¦”\ÀіĬÓŒ¥rªFA#h6ÓÇɨßi°ÚÛZGìL­{}ä³ïfR€Œ%eÚr7£sVo|]ug{¬Ä©OÒgŠ+›Ÿ´áʼq¹eMœír < wÞ’ÃÞ±©KjžY’ÝŒ[&d`Á˜ù{ÈÚTqYËá¿×µû‹û‹È¬o/a”[G"yWHBñ‚ÀoV¹œŒP¯ãX­¼Qv4à²É,hmõ,èQó,;A@U[œŒÔRxÖæ×ã_¾Òà¶Óî#g¾øs+(O4 ÃNæÀ®CàË(o-f·­­Ü×Ú3Gå,’‰çäÜÃ÷®ybG®8¢/ÛG¦5µ=JK X^DÿD(ÁÆÁeJŒn-ÀÇJ—Ã&‹ÄIx«öO:ÎA†Îì\ÂÁ”0+ =H €AØœ­;Ä–ºx†8šÿP¼Ö¯­­’yÊ*ªM1ùŸ UU{+§Ólf±…Ò}JîýÙ³æ]ÁÀFŠ1øVtž³kDŠ«»y¢¾šþ˜™<È¥•œ¾2¥Jþñ†sÍP‡Æ7—ÒCe§èé&«þ‘ö‹y®ü¸áò\#~ð#nÉeÛòŒƒ“¶³-¼köŸ§Øâžyµ-&Ò[=9äÚüË1˜ò(U ÀºÉÀ­±à»H¢·6šŽ¡iyºö'C4¾k“~ä*rÀº1·‡Àº8T›ˆ+h-íäŽA¾$ÈQш'ï[$ä0à‚ ÈàñI–ÖÊcdÜêÓé…D¹ÛåÉ*oÎÞsåg}î¼s¯‹®¥dŸJHtöÕ%ÓâçsïY5}›ÚÌ }ì‚zÍNžµKØ'þÐÔ P^½üvÛ£‰ŸvóÂn —s‚q“Æ*–‡áŽi.u‹ÀV»¾ŽÈȆÍ4†98³µ”íÝ€y#4­ªëWvº­®—¦ééyw42\0–ãÉD ‚wml±.Ç\‘\V›ñtßiñ\y®£Ó’òäêŠÁ+†-…Œ0&I>SÆ@éós]Þ¥¢G¨^ÛÞ¥åÕÜñ,ÖÅ2Ѿ ) ¬1•SÓ#ÍfZø&ÛM‚Ú=/UÔìdµy!xÙ¦ *z0ÈÜß0óÖ€ÃÆÚ^$m2lãˆm*g¼1ÜJ¦0áã‡gÌŸ0ÝØñÅV²ñ5Ì“ÿgéšs]]½Õ󸺾!R8n d†*Ç’FÔÆã Ö›ÃisªÛ^ÝjwóÇm0žI ~ZH¨l„Üð[ô¬WçOòn4˜5‰®üë§2XÏnŽòyŽæávÆ—è¼>½¼²k«]Y"Ò£Õ&^l*¬ÒƒÂ·î‰Ï$cí{RŽÃ|«3G-Å QÆ&ēƣ‘Ûæäwë?@ðdVKK¹dûLÚLZuÈÁU æT‘œæVäõÀã­lÞh¶×º<d(†Õ”ÄÄêëž1ÉAž:g¥cÞxºê×PÔÐiHÖmä³Ü¬9óV&Ü©³¾hÈ,8< üS©jú}敼†îüÃ2O)Œ:ù¸\„rS9?( Å«Ÿ Y]Gª#Ë8•ÌW3maò´k€¼p1ç9ê õ=b+`n®-fµœ\A=¾ÍèûYs‡VS•vƒÖ€9øS†E†þÈÉgq­^Ù%Û]—ua4ÅB¿êÀ]€î`|¸æ¤³ø‹ey®Åb‚ËÈšñì£+~­s½K Í2¨Jây€ mÅá‹8­íáó®A¨I¨«3.ZWwrs#p1Ûš,ü:º}óKi©ßÅhÒ¼ÆÀÌ;Ü–b Mà$à62zP+»OWñ]Öe©É¦[XZÃ4²Áo,¯+8yŠÊÎxÉ'¨Ågø«WÖ4(¡†-C|«£ê7/ƒ|±$f6Æn<§jÞÔü;þ¢š½ýî|±y-=£&d$…eue H8ÈÉÁ桿𕞥oWWw²ì®,¼Ã .Ë8PìI{åì=(bÊGšÂÞW9w‰Y© WŸÜx¯X-­þÔ Å†¥pu'1/ÏiȽ1…>\ñ¶FËõ®ËGÒ.4 V]oPÔ#Øé`ôòãCù“U$ðv—.¥®^¹œ¾µn-îP°Ú«³a(1Á .IÏÝ™g®\]\ZÜ\<²Auâ ílÄrya#Ž)Wæ~ñKDç ÝÏÊfh,–ÿá”—b;›¸ltB×wÆé£’K…‡s"6 nåûcqÎ:»O ØÙéÚ-”rÜ2iùл°-#ìt%Î9ϘÄãþUJivºTºm¼÷‘[ϧg\uýòìØ²7Ë0/€èAÒÂÛ ¹åAäçµqŸð’êðžmó—þÿ´díØ?ãïËówîëùgŽ›«­¶³û4Ó8¹žE“nØä`V=ªËÆq“œó\çü+}“gÙÛ¼ÿ´ÿiìOµù¾g™¿ÌÛ×w¶1ÇJŽI(ÖX[°Ó’f6±Þn¼>[7C°mVÆA ÜëV4ÿ½âiLÑiÒBù­K Cí¦ ’\–Ø¿7îö•ÀÆsžÕa¼,$Ô ôÚΧ,é‘Û3‡Ùƒ‘»a‚zóÁ–À4Í©j¨5ÒÝý¼˜„¢EŒÆ0bïÎxëÓšæôÿݲÑÚâ+} RW¹Ô }æ|›ŠïˆÉÉÀ99#¾–­ã ‹_¶¾™¥-ô66 rÏs䬪 ÚÛ›IÉqÉ× C•oÌ«æ.I`zàVM‡f³Ò|@ñ[É©I¤O©OvòÎPD‰,Æ8ƒÙbªaWŸ@züa5ëÊ·7qZK4SÏa(‚Y# ˆÛ¸}ÄÈ Ú2 1ü¤¸œo¹_´›•¹*àyñÎîïñʆ•î½' k(þÉ}U~Çæÿgé-©­ÛæcÉÐãîuç¯J¡ã[½*)þWî!QvZ?-¤ÆWÙû½…”¶  £Vð„¿ØzûÁ{}¨êwºD–‹§Œgå}€mUîsÉüjí·„„æ]gT†‚;‚ñ3Áœì\ÆT‚z– NIÅjh×íªiPÞ7ØÏ™’ ÏÚ"#8dÚ¹ü…_¬ýGƒD²khe–c$¯<²ÌWt’9Ë1ÚŽ{µhPEPŸø·þJ÷ïû‰ÿé:× WŸø·þJ÷ïû‰ÿé:× PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPŸÿÍÂÿÜ©ÿ·uèçÿóp¿÷*íÝzQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEEu+Ai4ʪÍ3ï°ycÐ{ö®2?ˆbK=E£´±»»²’Ñ|½?QYâ\Kå.$Ø0ÀîÊ•ôç5Öêšm¾±¥]é·A½ÔM›NÖ85ÿm¬“\Ou©jSOö@Ï+F0-æ2ÆT ÄçŽG¡æ€3u¯ÿaݽ•ݾ˜—–öÂææ95A*KmXw 2¹NP2y­ÍkÄ ¥øpkAöˆßÊ)½ÌhªìwlªdœÒáõ»Ô›PµÔ¯´ë™"Xf{C&E$¨a"0ÈÜØ#žµvöÎK»/"+ë«G< Œ¾¬§>àÐV›âF¾¾Ó-Z6ûu¥ÍÈšÎóψž%[jîÏ›œàcn9ªZg‹ïµß!t½ìÑÜÝy÷†5ˆHX*©ÅÛäcÑGNy«0ø2ÖÙmÞÛQ¿†îÚí ~d¾q `Sn U?*ŒmÅ6ÏÁVºbZ7SÔ¬Ú tµw‰ãcqT>ô##s|ËƒÉæ€'Ó5û½NI®ÓO†=9&Œ]=Éó[ËfRÞPLm,§vqÎ+Ÿ³ø¡my M¥¼âK)o-¡³¾Yç!m’Æî؃œÝ<ŒšÇñé×’½½ýಒI%:{ÌÜ’Äe7€I'±“Ò¢²ðÃiÖÆÖÛ\ÕRÑ"ò­àÝëÛiò÷¼µeKã©!ÑmïÌZ;¬÷_gŪ–´ˆl-™&ò²‡#n6õ#žk;V×µK}vãT–Þ)ltÍêB }VEGlHO d Q»€>`3ÅtQxLÀ·»ªGyu(–âì7Ë… ©‹f”z[i6örZ3Û˧ 5ãwÈh²ÄöÎã½½½  ¾+×%‡Lñº¼3[èRÞÇs…YX¬€c‚ ç9®žÜ–¶ˆ’I( 'é\ÿü!–Ò¦¢.õ=JîKý?û:Y&x÷,_7Ý €ùÏ$|ÖµŽŸ%ÝìÏy4É;'•“¶T €3Œ’‰ëí’ÄO®ø†_ßÝÜÇ’q ­nO˜êº‚Æb#b€6™ÉÜ8É­ ß0Ik¨ÙYÚêKx¶ª’ß…¶;¢óC™™ ·#îgw浿á¶ò®­Íõ鵸½Káo˜öÅ*Ì'%NÍØg‚Oãëß YÞ^Ï|·7v÷’N“¥Ä,¡¡uŒÇòåH © † ho ëðøIûlB0RW†AÂTܧ«ŽO@x®@ñ.¥}â{‘q*>—© λBí6ï±òÀdïÎñžÀ⺨tù#Ò䳓Q¼žGVSu!A('¸Ú¡A¾\qXv¿|7aýšú}„vW:{+GunŠ“>¡ØËçׯZÎðÞ¥¨ÞL¶:Æ·ªZkWϾÊk¢HäÀÜÖïå‘ BxË>F kÑjòø‹ZŠïĺվ™x$2Cl«*µ¼R|å" Ò„tùÒ³ðÂÛê–ú…Þ­©j2Ú«­²Ý´{aÜ0HØŠX㌱'“ZZTÚ•ÜO!“Pg”1VXÒ0Ž˜ŒuÏ9  sÄ¿Øz¾¢Ëk$Í £’÷,°¨’iSs §`\eœHÇ-méz„Ú–Š—¨¶/,ŠÅ­ßàœbPƒ úíãÐÔWš Üê7„:…åÜðE’ܧʱ³°Àua’d`rÆ:TÚ6‰dÖÐË,ÆI^ye˜®é$s–c´öjóÍÄZ–•£ÛêÚ¬—K¥ÞêA†¯4‚SF*cdÚƒnBóÇ5Ðê'¹D’×QÓZÚ`Ö3F-¯NY%¹XðÌ`©ûÊ2g“WeðN›6‘o¦´÷b,.4õ`ë¸Ç0PÄü¸Ü6ŒqcVµ Ùjw_hš[…}&” C0™zŽì>Þh´({O¢,â¾ÓçÞì¸l ¾8v|ÉÎ3»±ãŠç|?ã{­/ÂMνfþCèæí.þÓæË9‰¶õ `¶ìƒ¹³ßºË%Þ¯ýÖ¥}4vóý¢61ùQÉ´¨ „Üð[ô¨?á Ò›KÓ´ÙŒóZØY=’+¸ýälЇqs…Œs@öÿ¢™g„[XÜ_ [Åa¨­Är4²yj­ Q°‚AnÇ ·JÒðÅö£w®xŠ=F3 \B‹Îe…ÈHçîŽIâ¬7…üû-ou­NñKFð¼Íx2²Œd‚ËnÎ9Ï4ûO ¥¢ê,š¦¢×7óG4×,è(¸@  Ž™  Ê(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿÅ¿òW¾ÜOÿIÖ½¼ÿÅ¿òW¾ÜOÿIÖ½€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€<ÿþnþåOý»¯@¯?ÿ›…ÿ¹SÿnëÐ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(‡ñ¿†üI©øÃz熤ҖëHûVSRi7šŠdàî;uªÿñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( þ.ÿýHßù7Gü]ÿú‘¿ònŠ(ÿ‹¿ÿR7þMÑÿþ¤oü›¢Š?âïÿÔÿ“tÅßÿ©ÿ&袀ø»ÿõ#äÝñwÿêFÿɺ( Ã~ñ‡ü,9 File Labeling Statements filecon Define entries for labeling files. The compiler will produce these entries in a file called file_contexts(5) by default in the cwd. The compiler option [-f|--filecontext <filename>] may be used to specify a different path or file name. Statement definition: Where: filecon The filecon keyword. path A string representing the file path that may be in the form of a regular expression. The string must be enclosed within double quotes (e.g. "/this/is/a/path(/.*)?") file_type A single keyword representing a file type in the file_contexts file as follows: keyword file_contexts entry file -- dir -d char -c block -b socket -s pipe -p symlink -l any no entry context_id The security context to be allocated to the file, which may be: A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. An empty context list represented by () can be used to indicate that matching files should not be re-labeled. This will be interpreted as <<none>> within the file_contexts(5) file. Examples: These examples use one named, one anonymous and one empty context definition: to resolve/build file_contexts entries of (assuming MLS enabled policy): >]]> fsuse Label filesystems that support SELinux security contexts. Statement definition: Where: fsuse The fsuse keyword. fstype A single keyword representing the type of filesystem as follows: task - For pseudo filesystems supporting task related services such as pipes and sockets. trans - For pseudo filesystems such as pseudo terminals and temporary objects. xattr - Filesystems supporting the extended attribute security.selinux. The labeling is persistent for filesystems that support extended attributes. fsname Name of the supported filesystem (e.g. ext4 or pipefs). context_id The security context to be allocated to the network interface. A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Examples: The context identifiers are declared in the file namespace and the fsuse statements in the global namespace: genfscon Used to allocate a security context to filesystems that cannot support any of the fsuse file labeling options. Generally a filesystem would have a single default security context assigned by genfscon from the root (/) that would then be inherited by all files and directories on that filesystem. The exception to this is the /proc filesystem, where directories can be labeled with a specific security context (as shown in the examples). Statement definition: Where: genfscon The genfscon keyword. fsname Name of the supported filesystem (e.g. rootfs or proc). path If fsname is proc, then the partial path (see examples). For all other types this must be ‘/’. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Examples: The context identifiers are declared in the file namespace and the genfscon statements are then inserted using the in container statement: libsepol-2.4/cil/docs/cil_mls_labeling_statements.xml000066400000000000000000001037211246370572200231530ustar00rootroot00000000000000 Multi-Level Security Labeling Statements Because there are many options for MLS labeling, the examples show a limited selection of statements, however there is a simple policy that will build shown in the levelrange section. sensitivity Declare a sensitivity identifier in the current namespace. Multiple sensitivity statements in the policy will form an ordered list. Statement definition: Where: sensitivity The sensitivity keyword. sensitivity_id The sensitivity identifier. Example: This example declares three sensitivity identifiers: sensitivityalias Declares a sensitivity alias identifier in the current namespace. See the sensitivityaliasactual statement for an example that associates the sensitivityalias identifier. Statement definition: Where: sensitivityalias The sensitivityalias keyword. sensitivityalias_id The sensitivityalias identifier. Example: See the sensitivityaliasactual statement. sensitivityaliasactual Associates a previously declared sensitivityalias identifier to a previously declared sensitivity identifier. Statement definition: Where: sensitivityaliasactual The sensitivityaliasactual keyword. sensitivityalias_id A single previously declared sensitivityalias identifier. sensitivity_id A single previously declared sensitivity identifier. Example: This example will associate sensitivity s0 with two sensitivity alias's: sensitivityorder Define the sensitivity order - lowest to highest. Multiple sensitivityorder statements in the policy will form an ordered list. Statement definition: Where: sensitivityorder The sensitivityorder keyword. sensitivity_id One or more previously declared sensitivity or sensitivityalias identifiers.. Example: This example shows two sensitivityorder statements that when compiled will form an ordered list. Note however that the second sensitivityorder statement starts with s2 so that the ordered list can be built. category Declare a category identifier in the current namespace. Multiple category statements declared in the policy will form an ordered list. Statement definition: Where: category The category keyword. category_id The category identifier. Example: This example declares a three category identifiers: categoryalias Declares a category alias identifier in the current namespace. See the categoryaliasactual statement for an example that associates the categoryalias identifier. Statement definition: Where: categoryalias The categoryalias keyword. categoryalias_id The categoryalias identifier. categoryaliasactual Associates a previously declared categoryalias identifier to a previously declared category identifier. Statement definition: Where: categoryaliasactual The categoryaliasactual keyword. categoryalias_id A single previously declared categoryalias identifier. category_id A single previously declared category identifier. Example: Declares a category c0, a category alias of documents, and then associates them: categoryorder Define the category order. Multiple categoryorder statements declared in the policy will form an ordered list. Note that this statement orders the categories to allow validation of category ranges. Statement definition: Where: categoryorder The categoryorder keyword. category_id One or more previously declared category or categoryalias identifiers. Example: This example orders one category alias and nine categories: categoryset Declare an identifier for a set of contiguous or non-contiguous categories in the current namespace. Notes: Category expressions are allowed in categoryset, sensitivitycategory, level, and levelrange statements. Category sets are not allowed in categoryorder statements. Statement definition: Where: categoryset The categoryset keyword. categoryset_id The categoryset identifier. category_id Zero or more previously declared category or categoryalias identifiers. Note that there must be at least one category_id identifier or expr parameter declared. expr Zero or more expr's, the valid operators and syntax are: (and (category_id ...) (category_id ...)) (or (category_id ...) (category_id ...)) (xor (category_id ...) (category_id ...)) (not (category_id ...)) (range category_id category_id) (all) Examples: These examples show a selection of categoryset statements: sensitivitycategory Associate a sensitivity identifier with one or more category's. Multiple definitions for the same sensitivity form an ordered list of categories for that sensitivity. This statement is required before a level identifier can be declared. Statement definition: Where: sensitivitycategory The sensitivitycategory keyword. sensitivity_id A single previously declared sensitivity or sensitivityalias identifier. categoryset_id A single previously declared categoryset (named or anonymous), or a list of category and/or categoryalias identifiers. The examples show each variation. Examples: These sensitivitycategory examples use a selection of category, categoryalias and categoryset's: level Declare a level identifier in the current namespace and associate it to a previously declared sensitivity and zero or more categories. Note that if categories are required, then before this statement can be resolved the sensitivitycategory statement must be used to associate categories with the sensitivity. Statement definition: Where: level The level keyword. level_id The level identifier. sensitivity_id A single previously declared sensitivity or sensitivityalias identifier. categoryset_id A single previously declared categoryset (named or anonymous), or a list of category and/or categoryalias identifiers. The examples show each variation. Examples: These level examples use a selection of category, categoryalias and categoryset's: levelrange Declare a level range identifier in the current namespace and associate a current and clearance level. Statement definition: Where: levelrange The levelrange keyword. levelrange_id The levelrange identifier. low_level_id The current level specified by a previously declared level identifier. This may be formed by named or anonymous components as discussed in the level section and shown in the examples. high_level_id The clearance or high level specified by a previously declared level identifier. This may be formed by named or anonymous components as discussed in the level section and shown in the examples. Examples: This example policy shows levelrange statement and all the other MLS labeling statements discussed in this section and will compile as a standalone policy: rangetransition Allows an objects level to transition to a different level. Generally used to ensure processes run with their correct MLS range, for example init would run at SystemHigh and needs to initialise / run other processes at their correct MLS range. Statement definition: Where: rangetransition The rangetransition keyword. source_type_id A single previously declared type, typealias or typeattribute identifier. target_type_id A single previously declared type, typealias or typeattribute identifier. class_id A single previously declared class or classmap identifier. new_range_id The new MLS range for the object class that is a previously declared levelrange identifier. This entry may also be defined as an anonymous or named level, sensitivity, sensitivityalias, category, categoryalias or categoryset identifier. Examples: This rule will transition the range of sshd.exec to s0 - s1:c0.c3 on execution from the init.process: mlsconstrain This is described in the Contraints section. mlsvalidatetrans This is described in the Contraints section. libsepol-2.4/cil/docs/cil_network_labeling_statements.xml000066400000000000000000000266211246370572200240540ustar00rootroot00000000000000 Network Labeling Statements ipaddr Declares a named IP address in IPv4 or IPv6 format that may be referenced by other CIL statements (i.e. netifcon). Notes: CIL statements utilising an IP address may reference a named IP address or use an anonymous address, the examples will show each option. IP Addresses may be declared without a previous declaration by enclosing within parentheses e.g. (127.0.0.1) or (::1). Statement definition: Where: ipaddr The ipaddr keyword. ipaddr_id The IP address identifier. ip_address A correctly formatted IP address in IPv4 or IPv6 format. Example: This example declares a named IP address and also passes an 'explicit anonymously declared' IP address to a macro: netifcon Label network interface objects (e.g. eth0). Statement definition: Where: netifcon The netifcon keyword. netif_name The network interface name (e.g. wlan0). netif_context_id The security context to be allocated to the network interface. A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. packet_context_id The security context to be allocated to packets. Note that these are defined but currently unused as the iptables(8) SECMARK services should be used to label packets. A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Examples: These examples show named and anonymous netifcon statements: nodecon Label network address objects that represent IPv4 or IPv6 IP addresses and network masks. IP Addresses may be declared without a previous declaration by enclosing within parentheses e.g. (127.0.0.1) or (::1). Statement definition: Where: nodecon The nodecon keyword. subnet_id A previously declared ipaddr identifier, or an anonymous IPv4 or IPv6 formatted address. netmask_id A previously declared ipaddr identifier, or an anonymous IPv4 or IPv6 formatted address. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Examples: These examples show named and anonymous nodecon statements: portcon Label a udp or tcp port. Statement definition: Where: portcon The portcon keyword. protocol The protocol keyword tcp or udp. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Examples: These examples show named and anonymous portcon statements: libsepol-2.4/cil/docs/cil_policy_config_statements.xml000066400000000000000000000132331246370572200233450ustar00rootroot00000000000000 Policy Configuration Statements mls Defines whether the policy is built as an MLS or non-MLS policy by the CIL compiler. There MUST only be one mls entry in the policy otherwise the compiler will exit with an error. Note that this can be over-ridden by the CIL compiler command line parameter -M true|false or --mls true|false flags. Statement definition: Where: mls The mls keyword. boolean Set to either true or false. Example: handleunknown Defines how the kernel will handle unknown object classes and permissions when loading the policy. There MUST only be one handleunknown entry in the policy otherwise the compiler will exit with an error. Note that this can be over-ridden by the CIL compiler command line parameter -U or --handle-unknown flags. Statement definition: Where: handleunknown The handleunknown keyword. action A keyword of either allow, deny or reject. The kernel will handle these keywords as follows: allow unknown class / permissions. This will set the returned AV with all 1's. deny unknown class / permissions (the default). This will set the returned AV with all 0's. reject loading the policy if it does not contain all the object classes / permissions. Example: This will allow unknown classes / permissions to be present in the policy: policycap Allow policy capabilities to be enabled via policy. These should be declared in the global namespace and be valid policy capabilities as they are checked against those known in libsepol by the CIL compiler. Statement definition: Where: policycap The policycap keyword. policycap_id The policycap identifer (e.g. open_perms). Example: These set two valid policy capabilities: libsepol-2.4/cil/docs/cil_role_statements.xml000066400000000000000000000415171246370572200214700ustar00rootroot00000000000000 Role Statements role Declares a role identifier in the current namespace. Statement definition: Where: role The role keyword. role_id The role identifier. Example: This example declares two roles: object_r in the global namespace and unconfined.role: roletype Authorises a role to access a type identifier. Statement definition: Where: roletype The roletype keyword. role_id A single previously declared role or roleattribute identifier. type_id A single previously declared type, typealias or typeattribute identifier. Example: This example will declare role and type identifiers, then associate them: roleattribute Declares a role attribute identifier in the current namespace. The identifier may have zero or more role and roleattribute identifiers associated to it via the typeattributeset statement. Statement definition: Where: roleattribute The roleattribute keyword. roleattribute_id The roleattribute identifier. Example: This example will declare a role attribute roles.role_holder that will have an empty set: roleattributeset Allows the association of one or more previously declared role identifiers to a roleattribute identifier. Expressions may be used to refine the associations as shown in the examples. Statement definition: Where: roleattributeset The roleattributeset keyword. roleattribute_id A single previously declared roleattribute identifier. role_id Zero or more previously declared role or roleattribute identifiers. Note that there must be at least one role_id or expr parameter declared. expr Zero or more expr's, the valid operators and syntax are: (and (role_id ...) (role_id ...)) (or (role_id ...) (role_id ...)) (xor (role_id ...) (role_id ...)) (not (role_id ...)) (all) Example: This example will declare three roles and two role attributes, then associate all the roles to them as shown: roleallow Authorise the current role to assume a new role. Notes: May require a roletransition rule to ensure transition to the new role. This rule is not allowed in booleanif statements. Statement definition: Where: roleallow The roleallow keyword. current_role_id A single previously declared role or roleattribute identifier. new_role_id A single previously declared role or roleattribute identifier. Example: See the roletransition statement for an example. roletransition Specify a role transition from the current role to a new role when computing a context for the target type. The class identifier would normally be process, however for kernel versions 2.6.39 with policy version >= 25 and above, any valid class may be used. Note that a roleallow rule must be used to authorise the transition. Statement definition: Where: roletransition The roletransition keyword. current_role_id A single previously declared role or roleattribute identifier. target_type_id A single previously declared type, typealias or typeattribute identifier. class_id A single previously declared class or classmap identifier. new_role_id A single previously declared role identifier to be set on transition. Example: This example will authorise the unconfined.role to assume the msg_filter.role role, and then transition to that role: rolebounds Defines a hierarchical relationship between roles where the child role cannot have more privileges than the parent. Notes: It is not possible to bind the parent role to more than one child role. While this is added to the binary policy, it is not enforced by the SELinux kernel services. Statement definition: Where: rolebounds The rolebounds keyword. parent_role_id A single previously declared role identifier. child_role_id A single previously declared role identifier. Example: In this example the role test cannot have greater priviledges than unconfined.role: libsepol-2.4/cil/docs/cil_sid_statements.xml000066400000000000000000000131301246370572200212740ustar00rootroot00000000000000 SID Statements sid Declares a new SID identifier in the current namespace. Statement definition: Where: sid The sid keyword. sid_id The sid identifier. Examples: These examples show three sid declarations: sidorder Defines the order of sid's. This is a mandatory statement when SIDs are defined. Multiple sidorder statements declared in the policy will form an ordered list. Statement definition: Where: sidorder The sidorder keyword. sid_id One or more sid identifiers. Example: This will produce an ordered list of "kernel security unlabeled" sidcontext Associates an SELinux security context to a previously declared sid identifier. Statement definition: Where: sidcontext The sidcontext keyword. sid_id A single previously declared sid identifier. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Examples: This shows two named security context examples plus an anonymous context: libsepol-2.4/cil/docs/cil_type_statements.xml000066400000000000000000000710001246370572200214760ustar00rootroot00000000000000 Type Statements type Declares a type identifier in the current namespace. Statement definition: Where: type The type keyword. type_id The type identifier. Example: This example declares a type identifier bluetooth.process: typealias Declares a type alias in the current namespace. Statement definition: Where: typealias The typealias keyword. typealias_id The typealias identifier. Example: See the typealiasactual statement for an example that associates the typealias identifier. typealiasactual Associates a previously declared typealias identifier to a previously declared type identifier. Statement definition: Where: typealiasactual The typealiasactual keyword. typealias_id A single previously declared typealias identifier. type_id A single previously declared type identifier. Example: This example will alias unconfined.process as unconfined_t in the global namespace: typeattribute Declares a type attribute identifier in the current namespace. The identifier may have zero or more type, typealias and typeattribute identifiers associated to it via the typeattributeset statement. Statement definition: Where: typeattribute The typeattribute keyword. typeattribute_id The typeattribute identifier. Example: This example declares a type attribute domain in global namespace that will have an empty set: typeattributeset Allows the association of one or more previously declared type, typealias or typeattribute identifiers to a typeattribute identifier. Expressions may be used to refine the associations as shown in the examples. Statement definition: Where: typeattributeset The typeattributeset keyword. typeattribute_id A single previously declared typeattribute identifier. type_id Zero or more previously declared type, typealias or typeattribute identifiers. Note that there must be at least one type_id or expr parameter declared. expr Zero or more expr's, the valid operators and syntax are: (and (type_id ...) (type_id ...)) (or (type_id ...) (type_id ...)) (xor (type_id ...) (type_id ...)) (not (type_id ...)) (all) Examples: This example will take all the policy types and exclude those in appdomain. It is equivalent to ~appdomain in the kernel policy language. This example is equivalent to { domain -kernel.process -ueventd.process -init.process } in the kernel policy language: typebounds This defines a hierarchical relationship between domains where the bounded domain cannot have more permissions than its bounding domain (the parent). Requires kernel 2.6.28 and above to control the security context associated to threads in multi-threaded applications. Note that an allow rule must be used to authorise the bounding. Statement definition: Where: typebounds The typebounds keyword. parent_type_id A single previously declared type or typealias identifier that is the parent domain. child_type_id A single previously declared type or typealias identifier that is the bound (child) domain. Example: In this example the httpd.child.process cannot have file (write) due to lack of permissions on httpd.process which is the parent. It means the child domain will always have equal or less privileges than the parent: typechange The type change rule is used to define a different label of an object for userspace SELinux-aware applications. These applications would use security_compute_relabel(3) and typechange rules in the policy to determine the new context to be applied. Note that an allow rule must be used to authorise the change. Statement definition: Where: typechange The typechange keyword. source_type_id A single previously declared type, typealias or typeattribute identifier. target_type_id A single previously declared type, typealias or typeattribute identifier. class_id A single previously declared class or classmap identifier. change_type_id A single previously declared type or typealias identifier that will become the new type. Example: Whenever security_compute_relabel(3) is called with the following parameters: scon=unconfined.object tcon=unconfined.object class=file the function will return a context of: unconfined.object:object_r:unconfined.change_label:s0 typemember The type member rule is used to define a new polyinstantiated label of an object for SELinux-aware applications. These applications would use avc_compute_member(3) or security_compute_member(3) with the typemember rules in the policy to determine the context to be applied. The application would then manage any required polyinstantiation. Note that an allow rule must be used to authorise the membership. Statement definition: Where: typemember The typemember keyword. source_type_id A single previously declared type, typealias or typeattribute identifier. target_type_id A single previously declared type, typealias or typeattribute identifier. class_id A single previously declared class or classmap identifier. member_type_id A single previously declared type or typealias identifier that will become the new member type. Example: Whenever avc_compute_member(3) or security_compute_member(3) is called with the following parameters: scon=unconfined.object tcon=unconfined.object class=file the function will return a context of: unconfined.object:object_r:unconfined.member_label:s0 typetransition The type transition rule specifies the labeling and object creation allowed between the source_type and target_type when a domain transition is requested. Kernels from 2.6.39 with policy versions from 25 and above also support a 'name transition' rule, however this is not allowed inside conditionals and currently only supports the file classes. Note that an allow rule must be used to authorise the transition. Statement definition: Where: typetransition The typetransition keyword. source_type_id A single previously declared type, typealias or typeattribute identifier. target_type_id A single previously declared type, typealias or typeattribute identifier. class_id A single previously declared class or classmap identifier. object_name A optional string within double quotes representing an object name for the 'name transition' rule. This string will be matched against the objects name (if a path then the last component of that path). If the string matches exactly, the default_type_id will then become the new type. default_type_id A single previously declared type or typealias identifier that will become the new type. Examples: This example shows a process transition rule with its supporting allow rule: This example shows a file object transition rule with its supporting allow rule: This example shows the 'name transition' rule with its supporting allow rule: typepermissive Policy database version 23 introduced the permissive statement to allow the named domain to run in permissive mode instead of running all SELinux domains in permissive mode (that was the only option prior to version 23). Note that the permissive statement only tests the source context for any policy denial. Statement definition: Where: typepermissive The typepermissive keyword. source_type_id A single previously declared type or typealias identifier. Example: This example will allow SELinux to run the healthd.process domain in permissive mode even when enforcing is enabled: libsepol-2.4/cil/docs/cil_user_statements.xml000066400000000000000000000443541246370572200215070ustar00rootroot00000000000000 User Statements user Declares an SELinux user identifier in the current namespace. Statement definition: Where: user The user keyword. user_id The SELinux user identifier. Example: This will declare an SELinux user as unconfined.user: userrole Associates a previously declared user identifier with a previously declared role identifier. Statement definition: Where: userrole The userrole keyword. user_id A previously declared SELinux user identifier. role_id A previously declared role or roleattribute identifier. Example: This example will associate unconfined.user to unconfined.role: userlevel Associates a previously declared user identifier with a previously declared level identifier. The level may be named or anonymous. Statement definition: Where: userlevel The userlevel keyword. user_id A previously declared SELinux user identifier. level_id A previously declared level identifier. This may consist of a single sensitivity with zero or more mixed named and anonymous category's as discussed in the level statement. Example: This example will associate unconfined.user with a named level of systemlow: userrange Associates a previously declared user identifer with a previously declared levelrange identifier. The levelrange may be named or anonymous. Statement definition: Where: userrange The userrange keyword. user_id A previously declared SELinux user identifier. levelrange_id A previously declared levelrange identifier. This may be formed by named or anonymous components as discussed in the levelrange statement and shown in the examples. Example: This example will associate unconfined.user with a named levelrange of low_high, other anonymous examples are also shown: userbounds Defines a hierarchical relationship between users where the child user cannot have more priviledges than the parent. Notes: It is not possible to bind the parent to more than one child. While this is added to the binary policy, it is not enforced by the SELinux kernel services. Statement definition: Where: userbounds The userbounds keyword. parent_user_id A previously declared SELinux user identifier. child_user_id A previously declared SELinux user identifier. Example: The user test cannot have greater priviledges than unconfined.user: userprefix Declare a user prefix that will be replaced by the file labeling utilities described at http://selinuxproject.org/page/PolicyStoreConfigurationFiles that details the file_contexts entries. Statement definition: Where: userprefix The userprefix keyword. user_id A previously declared SELinux user identifier. prefix The string to be used by the file labeling utilities. Example: This example will associate unconfined.admin user with a prefix of "user": selinuxuser Associates a GNU/Linux user to a previously declared user identifier with a previously declared MLS userrange. Note that the userrange is required even if the policy is non-MCS/MLS. Statement definition: Where: selinuxuser The selinuxuser keyword. user_name A string representing the GNU/Linux user name user_id A previously declared SELinux user identifier. userrange_id A previously declared userrange identifier that has been associated to the user identifier. This may be formed by named or anonymous components as discussed in the userrange statement and shown in the examples. Example: This example will associate unconfined.admin user with a GNU / Linux user "admin_1": selinuxuserdefault Declares the default SELinux user. Only one selinuxuserdefault statement is allowed in the policy. Note that the userrange identifier is required even if the policy is non-MCS/MLS. Statement definition: Where: selinuxuserdefault The selinuxuserdefault keyword. user_id A previously declared SELinux user identifier. userrange_id A previously declared userrange identifier that has been associated to the user identifier. This may be formed by named or anonymous components as discussed in the userrange statement and shown in the examples. Example: This example will define the unconfined.user as the default SELinux user: libsepol-2.4/cil/docs/cil_xen_statements.xml000066400000000000000000000216571246370572200213240ustar00rootroot00000000000000 Xen Statements See the "XSM/FLASK Configuration" document for further information () iomemcon Label i/o memory. This may be a single memory location or a range. Statement definition: Where: iomemcon The iomemcon keyword. mem_addr | (mem_low mem_high) A single memory address to apply the context, or a range of addresses. The entries must consist of numerics [0-9]. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Example: An anonymous context for a memory address range of 0xfebe0-0xfebff: ioportcon Label i/o ports. This may be a single port or a range. Statement definition: Where: ioportcon The ioportcon keyword. port | (port_low port_high) A single port to apply the context, or a range of ports. The entries must consist of numerics [0-9]. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Example: An anonymous context for a single port of :0xecc0: pcidevicecon Label a PCI device. Statement definition: Where: pcidevicecon The pcidevicecon keyword. device The device number.The entries must consist of numerics [0-9]. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Example: An anonymous context for a pci device address of 0xc800: pirqcon Label an interrupt level. Statement definition: Where: pirqcon The pirqcon keyword. irq_level The interrupt request number. The entries must consist of numerics [0-9]. context_id A previously declared context identifier or an anonymous security context (user role type levelrange), the range MUST be defined whether the policy is MLS/MCS enabled or not. Example: An anonymous context for IRQ 33: libsepol-2.4/cil/docs/secilc.8.xml000066400000000000000000000117471246370572200170430ustar00rootroot00000000000000 RichardHaines SECILC 8 12 May 2014 secilc SELinux CIL Compiler secilc invoke the SELinux Common Intermediate Language (CIL) Compiler secilc OPTION file DESCRIPTION secilc invokes the CIL compiler with the specified arguments to build a kernel binary policy. A file_contexts file will also be built as described in the FILE FORMAT section of file_contexts5. OPTIONS Write binary policy to file (default: policy.version) Write file contexts to file (default: file_contexts) Specify target architecture. May be selinux or xen (default: selinux) Build an mls policy. Must be true or false. This will override the (mls boolean) statement if present in the policy. Build a binary policy with a given version (default: depends on the systems SELinux policy version, see sestatus8) How to handle unknown classes or permissions. May be deny, allow, or reject (default: deny). This will override the (handleunknown action) statement if present in the policy. Do not add dontaudit rules to the binary policy. Treat tunables as booleans. Do not check neverallow rules. Increment verbosity level. Display usage information. SEE ALSO file_contexts 5 sestatus 8 HTML documentation describing the CIL language statements is available starting with docs/html/index.html. PDF documentation describing the CIL language statements is available at: docs/pdf/CIL_Reference_Guide.pdf. There is a CIL Design Wiki at: that describes the goals and features of the CIL language. libsepol-2.4/cil/include/000077500000000000000000000000001246370572200153725ustar00rootroot00000000000000libsepol-2.4/cil/include/cil/000077500000000000000000000000001246370572200161415ustar00rootroot00000000000000libsepol-2.4/cil/include/cil/cil.h000066400000000000000000000060121246370572200170600ustar00rootroot00000000000000/* * 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 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, char *name, char *data, size_t size); extern int cil_compile(cil_db_t *db, sepol_policydb_t *sepol_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, sepol_policydb_t *sepol_db, char **out, size_t *size); extern int cil_selinuxusers_to_string(cil_db_t *db, sepol_policydb_t *sepol_db, char **out, size_t *size); extern int cil_filecons_to_string(cil_db_t *db, sepol_policydb_t *sepol_db, char **out, size_t *size); extern void cil_set_disable_dontaudit(cil_db_t *db, int disable_dontaudit); 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); 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, 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)); #endif libsepol-2.4/cil/secilc.c000066400000000000000000000241471246370572200153650ustar00rootroot00000000000000/* * 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 void usage(char *prog) { printf("Usage: %s [OPTION]... FILE...\n", prog); printf("\n"); printf("Options:\n"); printf(" -o, --output= write binary policy to \n"); printf(" (default: policy.)\n"); printf(" -f, --filecontext= write file contexts to \n"); printf(" (default: file_contexts)\n"); printf(" -t, --target= specify target architecture. may be selinux or\n"); printf(" xen. (default: selinux)\n"); printf(" -M, --mls true|false build an mls policy. Must be true or false.\n"); printf(" This will override the (mls boolean) statement\n"); printf(" if present in the policy\n"); printf(" -c, --policyvers= build a binary policy with a given \n"); printf(" (default: %i)\n", POLICYDB_VERSION_MAX); printf(" -U, --handle-unknown= how to handle unknown classes or permissions.\n"); printf(" may be deny, allow, or reject. (default: deny)\n"); printf(" This will override the (handleunknown action)\n"); printf(" statement if present in the policy\n"); printf(" -D, --disable-dontaudit do not add dontaudit rules to the binary policy\n"); printf(" -P, --preserve-tunables treat tunables as booleans\n"); printf(" -N, --disable-neverallow do not check neverallow rules\n"); printf(" -v, --verbose increment verbosity level\n"); printf(" -h, --help display usage information\n"); exit(1); } int main(int argc, char *argv[]) { int rc = SEPOL_ERR; sepol_policydb_t *pdb = NULL; struct sepol_policy_file *pf = NULL; FILE *binary = NULL; FILE *file_contexts; FILE *file = NULL; char *buffer = NULL; struct stat filedata; uint32_t file_size; char *output = NULL; char *filecontexts = NULL; struct cil_db *db = NULL; int target = SEPOL_TARGET_SELINUX; int mls = -1; int disable_dontaudit = 0; int disable_neverallow = 0; int preserve_tunables = 0; int handle_unknown = -1; int policyvers = POLICYDB_VERSION_MAX; int opt_char; int opt_index = 0; char *fc_buf = NULL; size_t fc_size; enum cil_log_level log_level = CIL_ERR; static struct option long_opts[] = { {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, {"target", required_argument, 0, 't'}, {"mls", required_argument, 0, 'M'}, {"policyversion", required_argument, 0, 'c'}, {"handle-unknown", required_argument, 0, 'U'}, {"disable-dontaudit", no_argument, 0, 'D'}, {"disable-neverallow", no_argument, 0, 'N'}, {"preserve-tunables", no_argument, 0, 'P'}, {"output", required_argument, 0, 'o'}, {"filecontexts", required_argument, 0, 'f'}, {0, 0, 0, 0} }; int i; while (1) { opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:", long_opts, &opt_index); if (opt_char == -1) { break; } switch (opt_char) { case 'v': log_level++; break; case 't': if (!strcmp(optarg, "selinux")) { target = SEPOL_TARGET_SELINUX; } else if (!strcmp(optarg, "xen")) { target = SEPOL_TARGET_XEN; } else { fprintf(stderr, "Unknown target: %s\n", optarg); usage(argv[0]); } break; case 'M': if (!strcasecmp(optarg, "true") || !strcasecmp(optarg, "1")) { mls = 1; } else if (!strcasecmp(optarg, "false") || !strcasecmp(optarg, "0")) { mls = 0; } else { usage(argv[0]); } break; case 'c': { char *endptr = NULL; errno = 0; policyvers = strtol(optarg, &endptr, 10); if (errno != 0 || endptr == optarg || *endptr != '\0') { fprintf(stderr, "Bad policy version: %s\n", optarg); usage(argv[0]); } if (policyvers > POLICYDB_VERSION_MAX || policyvers < POLICYDB_VERSION_MIN) { fprintf(stderr, "Policy version must be between %d and %d\n", POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); usage(argv[0]); } break; } case 'U': if (!strcasecmp(optarg, "deny")) { handle_unknown = SEPOL_DENY_UNKNOWN; } else if (!strcasecmp(optarg, "allow")) { handle_unknown = SEPOL_ALLOW_UNKNOWN; } else if (!strcasecmp(optarg, "reject")) { handle_unknown = SEPOL_REJECT_UNKNOWN; } else { usage(argv[0]); } break; case 'D': disable_dontaudit = 1; break; case 'N': disable_neverallow = 1; break; case 'P': preserve_tunables = 1; break; case 'o': output = strdup(optarg); break; case 'f': filecontexts = strdup(optarg); break; case 'h': usage(argv[0]); case '?': break; default: fprintf(stderr, "Unsupported option: %s\n", optarg); usage(argv[0]); } } if (optind >= argc) { fprintf(stderr, "No cil files specified\n"); usage(argv[0]); } cil_set_log_level(log_level); cil_db_init(&db); cil_set_disable_dontaudit(db, disable_dontaudit); cil_set_disable_neverallow(db, disable_neverallow); cil_set_preserve_tunables(db, preserve_tunables); if (handle_unknown != -1) { rc = cil_set_handle_unknown(db, handle_unknown); if (rc != SEPOL_OK) { goto exit; } } cil_set_mls(db, mls); for (i = optind; i < argc; i++) { file = fopen(argv[i], "r"); if (!file) { cil_log(CIL_ERR, "Could not open file: %s\n", argv[i]); rc = SEPOL_ERR; goto exit; } rc = stat(argv[i], &filedata); if (rc == -1) { cil_log(CIL_ERR, "Could not stat file: %s\n", argv[i]); goto exit; } file_size = filedata.st_size; buffer = malloc(file_size); rc = fread(buffer, file_size, 1, file); if (rc != 1) { cil_log(CIL_ERR, "Failure reading file: %s\n", argv[i]); goto exit; } fclose(file); file = NULL; rc = cil_add_file(db, argv[i], buffer, file_size); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failure adding %s\n", argv[i]); goto exit; } free(buffer); buffer = NULL; } rc = sepol_policydb_create(&pdb); if (rc < 0) { cil_log(CIL_ERR, "Failed to create policy db\n"); goto exit; } pdb->p.policy_type = POLICY_KERN; pdb->p.target_platform = target; rc = sepol_policydb_set_vers(pdb, policyvers); if (rc != 0) { cil_log(CIL_ERR, "Failed to set policy version: %d\n", rc); goto exit; } rc = cil_compile(db, pdb); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to compile cildb: %d\n", rc); goto exit; } rc = cil_build_policydb(db, pdb); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to build policydb\n"); goto exit; } if (output == NULL) { int size = snprintf(NULL, 0, "policy.%d", policyvers); output = malloc((size + 1) * sizeof(char)); if (output == NULL) { cil_log(CIL_ERR, "Failed to create output filename\n"); rc = SEPOL_ERR; goto exit; } if (snprintf(output, size + 1, "policy.%d", policyvers) != size) { cil_log(CIL_ERR, "Failed to create output filename\n"); rc = SEPOL_ERR; goto exit; } } cil_log(CIL_INFO, "Writing binary to %s\n", output); binary = fopen(output, "w"); if (binary == NULL) { cil_log(CIL_ERR, "Failure opening binary file for writing\n"); rc = SEPOL_ERR; goto exit; } rc = sepol_policy_file_create(&pf); if (rc != 0) { cil_log(CIL_ERR, "Failed to create policy file: %d\n", rc); goto exit; } sepol_policy_file_set_fp(pf, binary); rc = sepol_policydb_write(pdb, pf); if (rc != 0) { cil_log(CIL_ERR, "Failed to write binary policy: %d\n", rc); goto exit; } fclose(binary); binary = NULL; cil_log(CIL_INFO, "Writing file contexts\n"); rc = cil_filecons_to_string(db, pdb, &fc_buf, &fc_size); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to get file context data\n"); goto exit; } if (filecontexts == NULL) { file_contexts = fopen("file_contexts", "w+"); } else { file_contexts = fopen(filecontexts, "w+"); } if (file_contexts == NULL) { cil_log(CIL_ERR, "Failed to open file_contexts file\n"); goto exit; } if (fwrite(fc_buf, sizeof(char), fc_size, file_contexts) != fc_size) { cil_log(CIL_ERR, "Failed to write file_contexts file\n"); goto exit; } fclose(file_contexts); file_contexts = NULL; rc = SEPOL_OK; exit: cil_log(CIL_INFO,"Exiting\n"); if (binary != NULL) { fclose(binary); } if (file != NULL) { fclose(file); } free(buffer); free(output); free(filecontexts); cil_db_destroy(&db); sepol_policydb_free(pdb); sepol_policy_file_free(pf); free(fc_buf); return rc; } libsepol-2.4/cil/src/000077500000000000000000000000001246370572200145365ustar00rootroot00000000000000libsepol-2.4/cil/src/cil.c000066400000000000000000001563141246370572200154630ustar00rootroot00000000000000/* * 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" 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, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, {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} }; 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_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_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_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_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_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_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_ROOT = cil_strpool_add(""); CIL_KEY_NODE = cil_strpool_add(""); CIL_KEY_PERM = cil_strpool_add("perm"); } 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); (*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)->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)->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)->num_types = 0; (*db)->num_roles = 0; (*db)->num_cats = 0; (*db)->val_to_type = NULL; (*db)->val_to_role = NULL; (*db)->disable_dontaudit = CIL_FALSE; (*db)->disable_neverallow = CIL_FALSE; (*db)->preserve_tunables = CIL_FALSE; (*db)->handle_unknown = -1; (*db)->mls = -1; } void cil_db_destroy(struct cil_db **db) { if (db == NULL || *db == NULL) { return; } cil_tree_destroy(&(*db)->parse); cil_destroy_ast_symtabs((*db)->ast->root); 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)->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)->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); *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, char *name, 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_ERR, "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, sepol_policydb_t *sepol_db) { int rc = SEPOL_ERR; if (db == NULL || sepol_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_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_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_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_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: cil_destroy_avrule(*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_PORTCON: cil_destroy_portcon(*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_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_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: *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; 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_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_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_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_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_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_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, __attribute__((unused)) sepol_policydb_t *sepol_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.name) + 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.name, userprefix->prefix_str); str_len -= buf_pos; str_tmp += buf_pos; } rc = SEPOL_OK; exit: return rc; } static int cil_level_equals(policydb_t *pdb, struct cil_level *low, struct cil_level *high) { mls_level_t l; mls_level_t h; int rc; cil_level_to_mls_level(pdb, low, &l); cil_level_to_mls_level(pdb, high, &h); rc = mls_level_eq(&l, &h); mls_level_destroy(&l); mls_level_destroy(&h); 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.name); 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.name; first = cat->value; last = first; } else if (cat->value == last + 1) { last++; str2 = cat->datum.name; } else { if (first == last) { str_len += strlen(str1) + strlen(cat->datum.name) + 1; } else if (last == first + 1) { str_len += strlen(str1) + strlen(str2) + strlen(cat->datum.name) + 2; } else { str_len += strlen(str1) + strlen(str2) + strlen(cat->datum.name) + 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.name); 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.name; first = cat->value; last = first; } else if (cat->value == last + 1) { last++; str2 = cat->datum.name; } else { if (first == last) { buf_pos = sprintf(str_tmp, "%s,%s", str1, cat->datum.name); str_tmp += buf_pos; } else if (last == first + 1) { buf_pos = sprintf(str_tmp, "%s,%s,%s", str1, str2, cat->datum.name); str_tmp += buf_pos; } else { buf_pos = sprintf(str_tmp, "%s.%s,%s",str1, str2, cat->datum.name); 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, sepol_policydb_t *sepol_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.name) + 1; if (sepol_db->p.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.name); str_tmp += buf_pos; if (sepol_db->p.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, sepol_policydb_t *sepol_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.name) + strlen(role->datum.name) + strlen(type->datum.name) + 3); if (sepol_db->p.mls == CIL_TRUE) { struct cil_levelrange *range = ctx->range; if (cil_level_equals(&sepol_db->p, 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_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.name, role->datum.name, type->datum.name); str_tmp += buf_pos; if (sepol_db->p.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(&sepol_db->p, 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_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_symtab_array_init(symtab_t symtab[], 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_log(CIL_ERR, "Failed to get symtab from node at line %d of %s\n", ast_node->line, ast_node->path); return SEPOL_ERR; } 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_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; } void cil_blockinherit_init(struct cil_blockinherit **inherit) { *inherit = cil_malloc(sizeof(**inherit)); (*inherit)->block_str = 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)->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; } 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_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)->rule_kind = CIL_NONE; (*avrule)->src_str = NULL; (*avrule)->src = NULL; (*avrule)->tgt_str = NULL; (*avrule)->tgt = NULL; (*avrule)->classperms = 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 = 0; (*filecon)->context_str = NULL; (*filecon)->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)->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_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; } 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; } libsepol-2.4/cil/src/cil_binary.c000066400000000000000000003017301246370572200170210ustar00rootroot00000000000000/* * 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 #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" /* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended * size of a hashtable. The next power of 2 of this is 2 ** 16. */ #define FILENAME_TRANS_TABLE_SIZE 1 << 16 #define RANGE_TRANS_TABLE_SIZE 1 << 13 #define ROLE_TRANS_TABLE_SIZE 1 << 10 struct cil_args_binary { const struct cil_db *db; policydb_t *pdb; struct cil_list *neverallows; int pass; hashtab_t filename_trans_table; hashtab_t range_trans_table; hashtab_t role_trans_table; }; struct cil_args_booleanif { const struct cil_db *db; policydb_t *pdb; cond_node_t *cond_node; enum cil_flavor cond_flavor; struct cil_list *neverallows; hashtab_t filename_trans_table; }; struct cil_neverallow { struct cil_tree_node *node; struct cil_list *rules; }; struct cil_neverallow_rule { struct cil_symtab_datum *src; struct cil_symtab_datum *tgt; uint32_t class; uint32_t perms; }; void cil_neverallows_list_destroy(struct cil_list *neverallows) { struct cil_list_item *i; struct cil_list_item *j; cil_list_for_each(i, neverallows) { struct cil_neverallow *neverallow = i->data; cil_list_for_each(j, neverallow->rules) { struct cil_neverallow_rule *rule = j->data; free(rule); } cil_list_destroy(&neverallow->rules, CIL_FALSE); free(neverallow); } cil_list_destroy(&neverallows, CIL_FALSE); } 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->name); if (*sepol_user == NULL) { cil_log(CIL_INFO, "Failed to find user %s in sepol hashtab\n", datum->name); 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->name); if (*sepol_role == NULL) { cil_log(CIL_INFO, "Failed to find role %s in sepol hashtab\n", datum->name); 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->name); if (*sepol_type == NULL) { cil_log(CIL_INFO, "Failed to find type %s in sepol hashtab\n", datum->name); 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->name); if (*sepol_class == NULL) { cil_log(CIL_INFO, "Failed to find class %s in sepol hashtab\n", datum->name); 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->name); if (*sepol_cat == NULL) { cil_log(CIL_INFO, "Failed to find category %s in sepol hashtab\n", datum->name); 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->name); if (*sepol_level == NULL) { cil_log(CIL_INFO, "Failed to find level %s in sepol hashtab\n", datum->name); return SEPOL_ERR; } return SEPOL_OK; } static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new) { struct cil_tree_node *node = datum->nodes->head->data; if (node->flavor == CIL_ROLEATTRIBUTE) { struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; if (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 (ebitmap_set_bit(new, role->value, 1)) { cil_log(CIL_ERR, "Failed to set role bit\n"); 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 = datum->nodes->head->data; if (node->flavor == CIL_TYPEATTRIBUTE) { struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; if (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 (ebitmap_set_bit(new, type->value, 1)) { cil_log(CIL_ERR, "Failed to set type bit\n"); 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; } 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; } static 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; } 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.name); rc = 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 = 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.name); 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; } int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db) { 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; struct cil_tree_node *node = cil_class->datum.nodes->head->data; struct cil_tree_node *cil_perm = node->cl_head; 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.name); rc = 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; rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE); if (rc != SEPOL_OK) { goto exit; } if (cil_class->common != NULL) { struct cil_class *cil_common = cil_class->common; key = cil_class->common->datum.name; 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; } while (cil_perm != NULL) { struct cil_perm *curr_perm = 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_perm->datum.name); 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++; cil_perm = cil_perm->next; } } 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.name == 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.name); rc = symtab_insert(pdb, SYM_ROLES, (hashtab_key_t)key, sepol_role, SCOPE_DECL, 0, &value); if (rc != SEPOL_OK) { goto exit; } if (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; } 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.name); 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_bit(role->types, tnode, i) { if (!ebitmap_get_bit(role->types, i)) continue; rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); if (rc != SEPOL_OK) goto exit; if (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) { 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.name); rc = 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; return SEPOL_OK; exit: free(key); type_datum_destroy(sepol_type); free(sepol_type); return rc; } 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.name); 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.name); rc = 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 (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) { int rc = SEPOL_ERR; uint32_t value = 0; char *key = NULL; type_datum_t *sepol_attr = NULL; if (cil_attr->used == CIL_FALSE) { 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.name); rc = 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; return SEPOL_OK; exit: type_datum_destroy(sepol_attr); free(sepol_attr); return rc; } int __cil_typeattr_bitmap_init(policydb_t *pdb) { int rc = SEPOL_ERR; pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); uint32_t i = 0; for (i = 0; i < pdb->p_types.nprim; i++) { ebitmap_init(&pdb->type_attr_map[i]); if (ebitmap_set_bit(&pdb->type_attr_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->used == CIL_FALSE) { 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_bit(cil_attr->types, tnode, i) { if (!ebitmap_get_bit(cil_attr->types, i)) continue; rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); if (rc != SEPOL_OK) goto exit; ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], 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.name); if (capnum == -1) { goto exit; } if (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.name); rc = 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; } 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.name); return SEPOL_ERR; } int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole) { int rc = SEPOL_ERR; user_datum_t *sepol_user = NULL; role_datum_t *sepol_role = NULL; ebitmap_t role_bitmap; ebitmap_node_t *rnode; unsigned int i; rc = __cil_get_sepol_user_datum(pdb, DATUM(userrole->user), &sepol_user); if (rc != SEPOL_OK) goto exit; rc = __cil_expand_role(userrole->role, &role_bitmap); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&role_bitmap, rnode, i) { if (!ebitmap_get_bit(&role_bitmap, i)) continue; 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 (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"); goto exit; } } rc = SEPOL_OK; exit: ebitmap_destroy(&role_bitmap); 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.name); rc = 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.name); rc = 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.name); rc = symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL); if (rc != SEPOL_OK) { free(key); 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.name); rc = 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; } 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.name); rc = 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_level); free(key); return rc; } 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 = 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; } 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; } int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, 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 = 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\n"); rc = SEPOL_ERR; } goto exit; } if (!cond_node) { rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum); } else { existing = 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\n"); 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; } 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; uint16_t kind = cil_rule->rule_kind; type_datum_t *sepol_src = NULL; type_datum_t *sepol_tgt = NULL; class_datum_t *sepol_obj = NULL; struct cil_list *class_list; type_datum_t *sepol_result = NULL; ebitmap_t src_bitmap, tgt_bitmap; ebitmap_node_t *node1, *node2; unsigned int i, j; struct cil_list_item *c; rc = __cil_expand_type(cil_rule->src, &src_bitmap); if (rc != SEPOL_OK) goto exit; rc = __cil_expand_type(cil_rule->tgt, &tgt_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; ebitmap_for_each_bit(&src_bitmap, node1, i) { if (!ebitmap_get_bit(&src_bitmap, i)) continue; rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&tgt_bitmap, node2, j) { if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 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_obj); if (rc != SEPOL_OK) goto exit; rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cond_node, cond_flavor); if (rc != SEPOL_OK) goto exit; } } } rc = SEPOL_OK; exit: ebitmap_destroy(&src_bitmap); 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); } 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, hashtab_t filename_trans_table) { 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; type_datum_t *sepol_result = NULL; filename_trans_t *new = NULL; ebitmap_t src_bitmap, tgt_bitmap; ebitmap_node_t *node1, *node2; unsigned int i, j; struct cil_list_item *c; char *name = DATUM(typetrans->name)->name; uint32_t *otype = NULL; 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; return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor); } rc = __cil_expand_type(typetrans->src, &src_bitmap); if (rc != SEPOL_OK) goto exit; rc = __cil_expand_type(typetrans->tgt, &tgt_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; ebitmap_for_each_bit(&src_bitmap, node1, i) { if (!ebitmap_get_bit(&src_bitmap, i)) continue; rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&tgt_bitmap, node2, j) { if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 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->stype = sepol_src->s.value; new->ttype = sepol_tgt->s.value; new->tclass = sepol_obj->s.value; new->otype = sepol_result->s.value; new->name = cil_strdup(name); rc = hashtab_insert(filename_trans_table, (hashtab_key_t)new, &(new->otype)); if (rc != SEPOL_OK) { if (rc == SEPOL_EEXIST) { add = CIL_FALSE; otype = hashtab_search(filename_trans_table, (hashtab_key_t)new); if (new->otype != *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 (add == CIL_TRUE) { new->next = pdb->filename_trans; pdb->filename_trans = new; } else { free(new->name); free(new); if (rc != SEPOL_OK) { goto exit; } } } } } rc = SEPOL_OK; exit: ebitmap_destroy(&src_bitmap); 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, hashtab_t filename_trans_table) { return __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE, filename_trans_table); } 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) { perm_datum_t *sepol_perm; cil_perm = curr_perm->data; key = cil_perm->datum.name; sepol_perm = hashtab_search(sepol_class->permissions.table, key); if (sepol_perm == NULL) { common_datum_t *sepol_common = sepol_class->comdatum; sepol_perm = hashtab_search(sepol_common->permissions.table, key); if (sepol_perm == NULL) { cil_log(CIL_ERR, "Failed to find datum for perm %s\n", key); rc = SEPOL_ERR; goto exit; } } data |= 1 << (sepol_perm->s.value - 1); } *datum = data; return SEPOL_OK; exit: return rc; } 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 = 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 void __cil_neverallow_handle(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms) { struct cil_neverallow *neverallow = neverallows->head->data; struct cil_list *neverallow_rules = neverallow->rules; struct cil_neverallow_rule *new = NULL; new = cil_malloc(sizeof(*new)); new->src = src; new->tgt = tgt; new->class = class; new->perms = perms; cil_list_append(neverallow_rules, CIL_LIST_ITEM, new); } static int __cil_is_type_match(enum cil_flavor f1, struct cil_symtab_datum *t1, enum cil_flavor f2, struct cil_symtab_datum *t2) { if (t1->name == t2->name) { return CIL_TRUE; } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { struct cil_typeattribute *a = (struct cil_typeattribute *)t1; struct cil_type *t = (struct cil_type *)t2; if (ebitmap_get_bit(a->types, t->value)) { return CIL_TRUE; } } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { struct cil_typeattribute *a = (struct cil_typeattribute *)t2; struct cil_type *t = (struct cil_type *)t1; if (ebitmap_get_bit(a->types, t->value)) { return CIL_TRUE; } } else if (f1 == CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { struct cil_typeattribute *a1 = (struct cil_typeattribute *)t2; struct cil_typeattribute *a2 = (struct cil_typeattribute *)t1; /* abusing the ebitmap abstraction for speed */ ebitmap_node_t *n1 = a1->types->node; ebitmap_node_t *n2 = a2->types->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 CIL_TRUE; } n1 = n1->next; n2 = n2->next; } } } return CIL_FALSE; } static int __cil_check_neverallows(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms) { struct cil_list_item *curr = NULL; enum cil_flavor al_src_flavor = ((struct cil_tree_node*)src->nodes->head->data)->flavor; enum cil_flavor al_tgt_flavor = ((struct cil_tree_node*)tgt->nodes->head->data)->flavor; cil_list_for_each(curr, neverallows) { struct cil_neverallow *neverallow = curr->data; struct cil_tree_node *node = neverallow->node; struct cil_list_item *curr_item = NULL; cil_list_for_each(curr_item, neverallow->rules) { struct cil_neverallow_rule *curr_rule = curr_item->data; enum cil_flavor nv_src_flavor = ((struct cil_tree_node*)curr_rule->src->nodes->head->data)->flavor; enum cil_flavor nv_tgt_flavor = ((struct cil_tree_node*)curr_rule->tgt->nodes->head->data)->flavor; if ((curr_rule->perms & perms) && (class == curr_rule->class)) { int src_match = __cil_is_type_match(al_src_flavor, src, nv_src_flavor, curr_rule->src); if (src_match) { int tgt_match = __cil_is_type_match(al_tgt_flavor, tgt, nv_tgt_flavor, curr_rule->tgt); if (tgt_match) { cil_log(CIL_ERR, "Neverallow found that matches avrule at line %d of %s\n", node->line, node->path); return SEPOL_ERR; } } } } } return SEPOL_OK; } 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, struct cil_list *neverallows, 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_NEVERALLOW) { __cil_neverallow_handle(neverallows, src, tgt, sepol_class->s.value, data); } else { if (kind == CIL_AVRULE_DONTAUDIT) { data = ~data; } else if (neverallows != NULL && kind == CIL_AVRULE_ALLOWED) { rc = __cil_check_neverallows(neverallows, src, tgt, sepol_class->s.value, data); if (rc != SEPOL_OK) { goto exit; } } 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; } int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, struct cil_list *neverallows, 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, neverallows, 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, neverallows, 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, neverallows, cond_node, cond_flavor); if (rc != SEPOL_OK) { goto exit; } } } return SEPOL_OK; exit: return rc; } int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows, 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->classperms; 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; } if (cil_avrule->rule_kind == CIL_AVRULE_NEVERALLOW && db->disable_neverallow == CIL_TRUE) { // ignore neverallow rules rc = SEPOL_OK; goto exit; } src = cil_avrule->src; tgt = cil_avrule->tgt; if (tgt->name == CIL_KEY_SELF) { ebitmap_t type_bitmap; ebitmap_node_t *tnode; unsigned int i; rc = __cil_expand_type(src, &type_bitmap); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&type_bitmap, tnode, i) { if (!ebitmap_get_bit(&type_bitmap, i)) continue; src = DATUM(db->val_to_type[i]); rc = __cil_avrule_expand(pdb, kind, src, src, classperms, neverallows, cond_node, cond_flavor); if (rc != SEPOL_OK) { ebitmap_destroy(&type_bitmap); goto exit; } } ebitmap_destroy(&type_bitmap); } else { rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, neverallows, cond_node, cond_flavor); if (rc != SEPOL_OK) goto exit; } return SEPOL_OK; exit: return rc; } int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows) { return __cil_avrule_to_avtab(pdb, db, cil_avrule, neverallows, NULL, CIL_FALSE); } 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; hashtab_t filename_trans_table = args->filename_trans_table; flavor = node->flavor; switch (flavor) { case CIL_NAMETYPETRANSITION: cil_typetrans = (struct cil_nametypetransition*)node->data; if (DATUM(cil_typetrans->name)->name != CIL_KEY_STAR) { cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n"); cil_log(CIL_ERR,"Invalid typetransition statement at line %d of %s\n", node->line, node->path); goto exit; } rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to insert type transition into avtab at line %d of %s\n", node->line, node->path); 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_log(CIL_ERR, "Failed to insert typerule into avtab at line %d of %s\n", node->line, node->path); goto exit; } break; case CIL_AVRULE: cil_avrule = node->data; rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, args->neverallows, cond_node, cond_flavor); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path); goto exit; } break; case CIL_CALL: case CIL_TUNABLEIF: break; default: cil_log(CIL_ERR, "Invalid statement within booleanif at line %d of %s\n", node->line, node->path); 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); 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)->name; 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)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: 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; } int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table) { 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 = node->cl_head; 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_log(CIL_INFO, "Failed to create sepol conditional node at line %d of %s\n", node->line, node->path); goto exit; } rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to convert CIL conditional expression to sepol expression at line %d of %s\n", node->line, node->path); 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); 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; bool_args.neverallows = neverallows; bool_args.filename_trans_table = filename_trans_table; 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_log(CIL_ERR, "Failure while walking true conditional block at line %d of %s\n", true_node->line, true_node->path); 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_log(CIL_ERR, "Failure while walking false conditional block at line %d of %s\n", false_node->line, false_node->path); goto exit; } } return SEPOL_OK; exit: 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; 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_bit(&role_bitmap, rnode, i) { if (!ebitmap_get_bit(&role_bitmap, i)) continue; rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&type_bitmap, tnode, j) { if (!ebitmap_get_bit(&type_bitmap, j)) continue; 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 = SEPOL_OK; 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: ebitmap_destroy(&role_bitmap); 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_bit(&src_bitmap, node1, i) { if (!ebitmap_get_bit(&src_bitmap, i)) continue; rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&tgt_bitmap, node2, j) { if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 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: ebitmap_destroy(&src_bitmap); ebitmap_destroy(&tgt_bitmap); return rc; } 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; rc = __cil_get_sepol_user_datum(pdb, item->data, &sepol_user); if (rc != SEPOL_OK) goto exit; if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) { goto exit; } } 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_bit(&role_bitmap, rnode, i) { if (!ebitmap_get_bit(&role_bitmap, i)) continue; rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role); if (rc != SEPOL_OK) { ebitmap_destroy(&role_bitmap); goto exit; } if (ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) { ebitmap_destroy(&role_bitmap); goto exit; } } 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) { ebitmap_destroy(&type_bitmap); goto exit; } if (ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1)) { ebitmap_destroy(&type_bitmap); goto exit; } } rc = __cil_expand_type(item->data, &type_bitmap); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&type_bitmap, tnode, i) { if (!ebitmap_get_bit(&type_bitmap, i)) continue; rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); if (rc != SEPOL_OK) { ebitmap_destroy(&type_bitmap); goto exit; } if (ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) { ebitmap_destroy(&type_bitmap); goto exit; } } ebitmap_destroy(&type_bitmap); } else { goto exit; } return SEPOL_OK; exit: return SEPOL_ERR; } 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)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)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)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; } 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; 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; } enum cil_flavor cil_op = (enum cil_flavor)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; } 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; } 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; } rc = __cil_constrain_expr_to_sepol_expr(pdb, db, 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: free(sepol_constrain); return rc; } 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; } 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; } 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 = DATUM(i->data)->nodes->head->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 = 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 = 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; } 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; } 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; } 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; } 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; if (cil_context != NULL) { ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail); count++; new_ocon->sid[0] = count; new_ocon->u.name = cil_strdup(cil_sid->datum.name); 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.name); 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, hashtab_t range_trans_table) { 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; range_trans_t *new; 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_bit(&src_bitmap, node1, i) { if (!ebitmap_get_bit(&src_bitmap, i)) continue; rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); if (rc != SEPOL_OK) goto exit; ebitmap_for_each_bit(&tgt_bitmap, node2, j) { if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 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_class); if (rc != SEPOL_OK) goto exit; new = cil_malloc(sizeof(*new)); memset(new, 0, sizeof(range_trans_t)); new->source_type = sepol_src->s.value; new->target_type = sepol_tgt->s.value; new->target_class = sepol_class->s.value; rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, &new->target_range); if (rc != SEPOL_OK) { free(new); goto exit; } rc = SEPOL_OK; rc = hashtab_insert(range_trans_table, (hashtab_key_t)new, &(new->target_range)); if (rc != SEPOL_OK) { if (rc == SEPOL_EEXIST) { add = CIL_FALSE; o_range = hashtab_search(range_trans_table, (hashtab_key_t)new); if (!mls_range_eq(&new->target_range, o_range)) { cil_log(CIL_ERR, "Conflicting Range transition rules\n"); } else { rc = SEPOL_OK; } } else { cil_log(CIL_ERR, "Out of memory\n"); } } if (add == CIL_TRUE) { new->next = pdb->range_tr; pdb->range_tr = new; } else { mls_range_destroy(&new->target_range); free(new); if (rc != SEPOL_OK) { goto exit; } } } } } rc = SEPOL_OK; exit: ebitmap_destroy(&src_bitmap); ebitmap_destroy(&tgt_bitmap); cil_list_destroy(&class_list, CIL_FALSE); 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; 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_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_addr32[0], 16); memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr32[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); 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; } 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; 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)->name); 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)->name); 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)->name); 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; } 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; 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)->name); goto exit; } } cil_list_destroy(&class_list, CIL_FALSE); } return SEPOL_OK; exit: cil_list_destroy(&class_list, CIL_FALSE); return SEPOL_ERR; } 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 filename_trans_table; hashtab_t range_trans_table; hashtab_t role_trans_table; db = args->db; pdb = args->pdb; pass = args->pass; filename_trans_table = args->filename_trans_table; range_trans_table = args->range_trans_table; role_trans_table = args->role_trans_table; if (node->flavor >= CIL_MIN_DECLARATIVE) { if (node != DATUM(node->data)->nodes->head->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); break; case CIL_TYPEATTRIBUTE: rc = cil_typeattribute_to_policydb(pdb, node->data); 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); } break; case CIL_USERROLE: 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: { struct cil_avrule *rule = node->data; struct cil_list *neverallows = args->neverallows; if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) { struct cil_neverallow *new_rule = NULL; new_rule = cil_malloc(sizeof(*new_rule)); cil_list_init(&new_rule->rules, CIL_LIST_ITEM); new_rule->node = node; cil_list_prepend(neverallows, CIL_LIST_ITEM, new_rule); rc = cil_avrule_to_policydb(pdb, db, node->data, neverallows); } 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, filename_trans_table); 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, range_trans_table); } 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, args->neverallows, filename_trans_table); 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, args->neverallows); } } break; case CIL_ROLEALLOW: rc = cil_roleallow_to_policydb(pdb, db, node->data); break; default: break; } default: break; } exit: if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Binary policy creation failed at line %d of %s\n", node->line, node->path); } return rc; } int __cil_binary_create_helper(struct cil_tree_node *node, __attribute__((unused)) 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_OPTIONAL) { struct cil_optional *opt = node->data; if (opt->datum.state != CIL_STATE_ENABLED) { *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; } 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; } if (pdb->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; } } return SEPOL_OK; exit: return rc; } 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; } 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; } 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; } 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; } 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; } 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; } 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; } 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; } 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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; } } } } int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db) { int rc = SEPOL_ERR; pdb->handle_unknown = db->handle_unknown; pdb->mls = db->mls; rc = cil_classorder_to_policydb(pdb, db); 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 = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE); if (rc != SEPOL_OK) { goto exit; } rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE); if (rc != SEPOL_OK) { goto exit; } return SEPOL_OK; exit: return rc; } static unsigned int filename_trans_hash(hashtab_t h, hashtab_key_t key) { filename_trans_t *k = (filename_trans_t *)key; return ((k->tclass + (k->ttype << 2) + (k->stype << 9)) & (h->size - 1)); } static int filename_trans_compare(hashtab_t h __attribute__ ((unused)), hashtab_key_t key1, hashtab_key_t key2) { filename_trans_t *a = (filename_trans_t *)key1; filename_trans_t *b = (filename_trans_t *)key2; return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name); } static unsigned int range_trans_hash(hashtab_t h, hashtab_key_t key) { range_trans_t *k = (range_trans_t *)key; return ((k->target_class + (k->target_type << 2) + (k->source_type << 5)) & (h->size - 1)); } static int range_trans_compare(hashtab_t h __attribute__ ((unused)), hashtab_key_t key1, hashtab_key_t key2) { range_trans_t *a = (range_trans_t *)key1; range_trans_t *b = (range_trans_t *)key2; return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class; } static unsigned int role_trans_hash(hashtab_t h, hashtab_key_t key) { role_trans_t *k = (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)), hashtab_key_t key1, hashtab_key_t key2) { role_trans_t *a = (role_trans_t *)key1; role_trans_t *b = (role_trans_t *)key2; return a->role != b->role || a->type != b->type || a->tclass != b->tclass; } int cil_binary_create(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 filename_trans_table = NULL; hashtab_t range_trans_table = NULL; hashtab_t role_trans_table = 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; } rc = __cil_policydb_init(pdb, db); if (rc != SEPOL_OK) { cil_log(CIL_ERR,"Problem in policydb_init\n"); return SEPOL_ERR; } filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE); if (!filename_trans_table) { cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n"); goto exit; } range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE); if (!range_trans_table) { cil_log(CIL_INFO, "Failure to create hashtab for range_trans\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; } cil_list_init(&neverallows, CIL_LIST_ITEM); extra_args.db = db; extra_args.pdb = pdb; extra_args.neverallows = neverallows; extra_args.filename_trans_table = filename_trans_table; extra_args.range_trans_table = range_trans_table; extra_args.role_trans_table = role_trans_table; 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; } } } 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); rc = SEPOL_OK; exit: hashtab_destroy(filename_trans_table); hashtab_destroy(range_trans_table); hashtab_destroy(role_trans_table); cil_neverallows_list_destroy(neverallows); return rc; } libsepol-2.4/cil/src/cil_binary.h000066400000000000000000000402771246370572200170340ustar00rootroot00000000000000/* * 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); /** * 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); /** * 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 perviously 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); /** * 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] datum The cil_userrole datum. * * @return SEPOL_OK upon success or SEPOL_ERR otherwise. */ int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole); /** * 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, struct cil_list *neverallows); /** * 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, struct cil_list *neverallows, hashtab_t filename_trans_table); /** * 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, hashtab_t filename_trans_table); /** * 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, hashtab_t range_trans_table); /** * 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_ libsepol-2.4/cil/src/cil_build_ast.c000066400000000000000000004356321246370572200175140ustar00rootroot00000000000000/* * 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 *macro; struct cil_tree_node *boolif; struct cil_tree_node *tunif; struct cil_tree_node *in; }; 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 }; int 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; } int cil_gen_node(__attribute__((unused)) 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((const char*)key); 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; if (symtab != NULL) { rc = cil_symtab_insert(symtab, (hashtab_key_t)key, datum, ast_node); if (rc == SEPOL_EEXIST) { cil_log(CIL_ERR, "Re-declaration of %s %s\n", cil_node_to_string(ast_node), key); if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) { if (sflavor == CIL_SYM_BLOCKS) { struct cil_tree_node *node = datum->nodes->head->data; cil_log(CIL_ERR, "Previous declaration at line %d of %s\n", node->line, node->path); } } goto exit; } } if (ast_node->flavor >= CIL_MIN_DECLARATIVE && ast_node->parent->flavor == CIL_MACRO) { struct cil_list_item *item; struct cil_list *param_list = ((struct cil_macro*)ast_node->parent->data)->params; if (param_list != NULL) { cil_list_for_each(item, param_list) { struct cil_param *param = item->data; if (param->flavor == ast_node->flavor) { if (param->str == key) { cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(ast_node), key); rc = SEPOL_ERR; goto exit; } } } } } return SEPOL_OK; exit: cil_log(CIL_ERR, "Failed to create node\n"); return rc; } 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(__attribute__((unused)) 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 }; int 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; } 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_log(CIL_ERR, "Bad block declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_block(block); cil_clear_node(ast_node); return rc; } void cil_destroy_block(struct cil_block *block) { if (block == NULL) { return; } cil_symtab_datum_destroy(&block->datum); cil_symtab_array_destroy(block->symtab); free(block); } int cil_gen_blockinherit(__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_END }; int 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; } 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_log(CIL_ERR, "Bad blockinherit declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_blockinherit(inherit); return rc; } void cil_destroy_blockinherit(struct cil_blockinherit *inherit) { if (inherit == NULL) { return; } free(inherit); } int cil_gen_blockabstract(__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_END }; int 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; } 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_log(CIL_ERR, "Bad blockabstract declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_blockabstract(abstract); return rc; } void cil_destroy_blockabstract(struct cil_blockabstract *abstract) { if (abstract == NULL) { return; } free(abstract); } int cil_gen_in(__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_N_LISTS, CIL_SYN_END }; int 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; } rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { goto exit; } cil_in_init(&in); in->block_str = parse_current->next->data; ast_node->data = in; ast_node->flavor = CIL_IN; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad in statement at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST | CIL_SYN_EMPTY_LIST, CIL_SYN_END }; int 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; 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; } } return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad class declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_END }; int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_classorder *classorder = 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; } ast_node->data = classorder; ast_node->flavor = CIL_CLASSORDER; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad classorder declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__attribute__((unused)) 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; 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(__attribute__((unused)) 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->path = current_perm->path; rc = cil_gen_perm(db, current_perm, new_ast, flavor, num_perms); if (rc != SEPOL_OK) { 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"); 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 }; int 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 }; int 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; enum cil_syntax syntax[] = { CIL_SYN_STRING | CIL_SYN_LIST, }; int syntax_len = sizeof(syntax)/sizeof(*syntax); if (parse_current == NULL || cp_list == NULL) { goto exit; } rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { 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(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad classpermission declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad classpermissionset at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad map class declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_class(map); cil_clear_node(ast_node); return rc; } int cil_gen_classmapping(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad classmapping declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_END }; int 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; } return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad common declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_class(common); cil_clear_node(ast_node); return rc; } int cil_gen_classcommon(__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_END }; int 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_log(CIL_ERR, "Bad classcommon declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_classcommon(clscom); return rc; } void cil_destroy_classcommon(struct cil_classcommon *clscom) { if (clscom == NULL) { return; } free(clscom); } int cil_gen_sid(__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_END }; int 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_log(CIL_ERR, "Bad sid declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad sidcontext declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_END }; int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_sidorder *sidorder = 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; } ast_node->data = sidorder; ast_node->flavor = CIL_SIDORDER; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad sidorder declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad user declaration at line %d of %s\n", parse_current->line, parse_current->path); 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); cil_list_destroy(&user->roles, CIL_FALSE); free(user); } int cil_gen_userlevel(__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_END }; int 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_log(CIL_ERR, "Bad userlevel declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad userrange declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad userprefix declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_userprefix(userprefix); return rc; } void cil_destroy_userprefix(struct cil_userprefix *userprefix) { if (userprefix == NULL) { return; } free(userprefix); } int cil_gen_selinuxuser(__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 }; int 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_log(CIL_ERR, "Bad selinuxuser declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_selinuxuser(selinuxuser); return rc; } int cil_gen_selinuxuserdefault(__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_END }; int 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_log(CIL_ERR, "Bad selinuxuserdefault declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad role declaration at line %d of %s\n", parse_current->line, parse_current->path); 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); ebitmap_destroy(role->types); free(role->types); free(role); } int cil_gen_roletype(__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_END }; int 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_log(CIL_ERR, "Bad roletype declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_roletype(roletype); return rc; } void cil_destroy_roletype(struct cil_roletype *roletype) { if (roletype == NULL) { return; } free(roletype); } int cil_gen_userrole(__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_END }; int 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_log(CIL_ERR, "Bad userrole declaration at line %d of %s\n", parse_current->line, parse_current->path); 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 }; int 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_log(CIL_ERR, "Bad roletransition rule at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_roletransition(roletrans); return rc; } void cil_destroy_roletransition(struct cil_roletransition *roletrans) { if (roletrans == NULL) { return; } free(roletrans); } int cil_gen_roleallow(__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_END }; int 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_log(CIL_ERR, "Bad roleallow rule at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_roleallow(roleallow); return rc; } void cil_destroy_roleallow(struct cil_roleallow *roleallow) { if (roleallow == NULL) { return; } free(roleallow); } int cil_gen_roleattribute(__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_END }; int 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; } if (parse_current->next->data == CIL_KEY_SELF) { cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); rc = SEPOL_ERR; 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_log(CIL_ERR, "Bad roleattribute declaration at line %d of %s\n", parse_current->line, parse_current->path); 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); ebitmap_destroy(attr->roles); free(attr->roles); free(attr); } int cil_gen_roleattributeset(__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_END }; int 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_log(CIL_ERR, "Bad roleattributeset declaration at line %d of %s\n", parse_current->line, parse_current->path); 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 }; int 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->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->classperms); if (rc != SEPOL_OK) { goto exit; } ast_node->data = rule; ast_node->flavor = CIL_AVRULE; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad allow rule at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_avrule(rule); return rc; } void cil_destroy_avrule(struct cil_avrule *rule) { if (rule == NULL) { return; } cil_destroy_classperms_list(&rule->classperms); free(rule); } 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 }; int 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_log(CIL_ERR, "Bad type rule at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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; } if (parse_current->next->data == CIL_KEY_SELF) { cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); rc = SEPOL_ERR; 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) { goto exit; } return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad type declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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; } if (parse_current->next->data == CIL_KEY_SELF) { cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); rc = SEPOL_ERR; 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) { goto exit; } return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad typeattribute declaration at line %d of %s\n", parse_current->line, parse_current->path); 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; } ebitmap_destroy(attr->types); free(attr->types); free(attr); } int cil_gen_bool(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad tunable (treated as a boolean due to preserve-tunables) declaration at line %d of %s\n", parse_current->line, parse_current->path); } else { cil_log(CIL_ERR, "Bad boolean declaration at line %d of %s\n", parse_current->line, parse_current->path); } 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(__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_END }; int 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_log(CIL_ERR, "Bad tunable declaration at line %d of %s\n", parse_current->line, parse_current->path); 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 */ else if (op == CIL_KEY_RANGE) return CIL_RANGE; /* Only catset */ else return CIL_NONE; } static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth); static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth) { int rc = SEPOL_ERR; enum cil_flavor op; if (flavor == CIL_BOOL && *depth > COND_EXPR_MAXDEPTH) { cil_log(CIL_ERR, "Max depth of %d exceeded for boolean expression\n", COND_EXPR_MAXDEPTH); goto exit; } 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; } if (op == CIL_NONE || op == CIL_ALL) { (*depth)++; } for (;current != NULL; current = current->next) { rc = __cil_fill_expr(current, flavor, expr, depth); if (rc != SEPOL_OK) { goto exit; } } (*depth)--; 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 *depth) { 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, depth); if (rc != SEPOL_OK) { 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; int depth = 0; cil_list_init(expr, flavor); if (current->cl_head == NULL) { rc = __cil_fill_expr(current, flavor, *expr, &depth); } else { rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr, &depth); } 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; cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list); 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 *depth) { 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; } if (*depth > CEXPR_MAXDEPTH) { cil_log(CIL_ERR, "Max depth of %d exceeded for constraint expression\n", CEXPR_MAXDEPTH); rc = SEPOL_ERR; 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: (*depth)++; 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, depth); 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, depth); if (rc != SEPOL_OK) { goto exit; } rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr, depth); 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); cil_list_append(*expr, CIL_LIST, rexpr); break; } (*depth)--; return SEPOL_OK; exit: return rc; } int cil_gen_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) { int rc = SEPOL_ERR; int depth = 0; if (current->cl_head == NULL) { goto exit; } rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr, &depth); 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(__attribute__((unused)) 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 }; int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_booleanif *bif = NULL; struct cil_tree_node *next = NULL; struct cil_tree_node *cond = 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; } cond = parse_current->next->next; /* Destroying expr tree after stack is created*/ if (cond->cl_head->data != CIL_KEY_CONDTRUE && cond->cl_head->data != CIL_KEY_CONDFALSE) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Conditional neither true nor false\n"); goto exit; } if (cond->next != NULL) { cond = cond->next; if (cond->cl_head->data != CIL_KEY_CONDTRUE && cond->cl_head->data != CIL_KEY_CONDFALSE) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Conditional neither true nor false\n"); goto exit; } } 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_log(CIL_ERR, "Bad tunableif (treated as a booleanif due to preserve-tunables) declaration at line %d of %s\n", parse_current->line, parse_current->path); } else { cil_log(CIL_ERR, "Bad booleanif declaration at line %d of %s\n", parse_current->line, parse_current->path); } 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(__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_LIST, CIL_SYN_LIST, CIL_SYN_LIST | CIL_SYN_END, CIL_SYN_END }; int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_tunableif *tif = NULL; struct cil_tree_node *next = NULL; struct cil_tree_node *cond = 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; } cond = parse_current->next->next; if (cond->cl_head->data != CIL_KEY_CONDTRUE && cond->cl_head->data != CIL_KEY_CONDFALSE) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Conditional neither true nor false\n"); goto exit; } if (cond->next != NULL) { cond = cond->next; if (cond->cl_head->data != CIL_KEY_CONDTRUE && cond->cl_head->data != CIL_KEY_CONDFALSE) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Conditional neither true nor false\n"); goto exit; } } /* Destroying expr tree after stack is created*/ 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_log(CIL_ERR, "Bad tunableif declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad %s condition declaration at line %d of %s\n", (char*)parse_current->data, parse_current->line, parse_current->path); 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(__attribute__((unused)) 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 }; int 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; } if (flavor == CIL_TYPEALIAS && parse_current->next->data == CIL_KEY_SELF) { cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); rc = SEPOL_ERR; 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_log(CIL_ERR, "Bad %s declaration at line %d of %s\n", (char*)parse_current->data, parse_current->line, parse_current->path); 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(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad %s association at line %d of %s\n", cil_node_to_string(parse_current),parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad typeattributeset statement at line %d of %s\n", parse_current->line, parse_current->path); 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_typepermissive(__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_END }; int 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_log(CIL_ERR, "Bad typepermissive declaration at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_typepermissive(typeperm); return rc; } void cil_destroy_typepermissive(struct cil_typepermissive *typeperm) { if (typeperm == NULL) { return; } free(typeperm); } int cil_gen_typetransition(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad typetransition declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_STRING | CIL_SYN_LIST, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad rangetransition declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad sensitivity declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad category declaration at line %d of %s\n", parse_current->line, parse_current->path); 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); } int cil_gen_catset(__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_LIST, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad categoryset declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_END }; int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_catorder *catorder = 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; } ast_node->data = catorder; ast_node->flavor = CIL_CATORDER; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad categoryorder declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_END }; int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_sensorder *sensorder = 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; } ast_node->data = sensorder; ast_node->flavor = CIL_SENSITIVITYORDER; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad sensitivityorder declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad sensitivitycategory declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad level declaration at line %d of %s\n", parse_current->line, parse_current->path); 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 }; int 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(__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_LIST, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad levelrange declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad constrain declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad validatetrans declaration at line %d of %s\n", parse_current->line, parse_current->path); 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 }; int 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(__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_LIST, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad context declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_EMPTY_LIST, CIL_SYN_END }; int 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_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 if (type == CIL_KEY_ANY) { filecon->type = CIL_FILECON_ANY; } 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_log(CIL_ERR, "Bad filecon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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_portcon(__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 }; int 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 { 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); 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); 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); 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_log(CIL_ERR, "Bad portcon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad nodecon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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 }; int syntax_len = sizeof(syntax)/sizeof(*syntax); 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->cl_head == NULL ) { genfscon->context_str = parse_current->next->next->next->data; } else { cil_context_init(&genfscon->context); rc = cil_fill_context(parse_current->next->next->next->cl_head, genfscon->context); if (rc != SEPOL_OK) { goto exit; } } ast_node->data = genfscon; ast_node->flavor = CIL_GENFSCON; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad genfscon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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 }; int 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_log(CIL_ERR, "Bad netifcon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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_pirqcon(__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_END }; int 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); 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_log(CIL_ERR, "Bad pirqcon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; int 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_integer(parse_current->next->cl_head, &iomemcon->iomem_low); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Improper iomem specified\n"); goto exit; } rc = cil_fill_integer(parse_current->next->cl_head->next, &iomemcon->iomem_high); 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_integer(parse_current->next, &iomemcon->iomem_low);; 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_log(CIL_ERR, "Bad iomemcon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST, CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; int 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); 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); 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); 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_log(CIL_ERR, "Bad ioportcon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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); 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_log(CIL_ERR, "Bad pcidevicecon declaration at line %d of %s\n", parse_current->line, parse_current->path); 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_fsuse(__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 }; int 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_log(CIL_ERR, "Bad fsuse declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__attribute__((unused)) 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; 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 }; int 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; struct cil_tree_node *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; 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(param->str); if (rc != SEPOL_OK) { cil_destroy_param(param); goto exit; } //walk current list and check for duplicate parameters struct cil_list_item *curr_param; cil_list_for_each(curr_param, macro->params) { if (param->str == ((struct cil_param*)curr_param->data)->str) { if (param->flavor == ((struct cil_param*)curr_param->data)->flavor) { 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_log(CIL_ERR, "Bad macro declaration at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_LIST | CIL_SYN_EMPTY_LIST | CIL_SYN_END, CIL_SYN_END }; int 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_log(CIL_ERR, "Bad macro call at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_N_LISTS | CIL_SYN_END, CIL_SYN_END }; int 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) goto exit; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad optional at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad policycap statement at line %d of %s\n", parse_current->line, parse_current->path); 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(__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_END }; int 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_log(CIL_ERR, "Bad ipaddr statement at line %d of %s\n", parse_current->line, parse_current->path); 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 rc = SEPOL_ERR; char *endptr = NULL; int val; if (int_node == NULL || integer == NULL) { goto exit; } errno = 0; val = strtol(int_node->data, &endptr, 10); if (errno != 0 || endptr == int_node->data || *endptr != '\0') { rc = SEPOL_ERR; goto exit; } *integer = val; return SEPOL_OK; exit: cil_log(CIL_ERR, "Failed to create integer from string\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 == NULL) { goto exit; } if (addr_node->cl_head != NULL || addr_node->next != NULL) { goto exit; } if (strchr(addr_node->data, '.') != NULL) { addr->family = AF_INET; } else { addr->family = AF_INET6; } 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\n"); 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 }; int 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); } 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(__attribute__((unused)) 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 }; int 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_log(CIL_ERR, "Bad bounds declaration at line %d of %s\n", parse_current->line, parse_current->path); 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 }; int 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); rc = SEPOL_OK; } else { rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); } 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_log(CIL_ERR, "Bad %s declaration at line %d of %s\n", cil_node_to_string(parse_current), parse_current->line, parse_current->path); 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 }; int 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); rc = SEPOL_OK; } else { rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASS, &def->class_strs); } object = parse_current->next->next->data; range = parse_current->next->next->next->data; if (object == CIL_KEY_SOURCE) { 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 (parse_current->next->next->data == CIL_KEY_TARGET) { 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 { cil_log(CIL_ERR,"Expected either \'source\' or \'target\'\n"); rc = SEPOL_ERR; goto exit; } ast_node->data = def; ast_node->flavor = CIL_DEFAULTRANGE; return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad defaultrange declaration at line %d of %s\n", parse_current->line, parse_current->path); 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 }; int 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_log(CIL_ERR, "Bad handleunknown at line %d of %s\n", parse_current->line, parse_current->path); 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 }; int 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_log(CIL_ERR, "Bad mls at line %d of %s\n", parse_current->line, parse_current->path); cil_destroy_mls(mls); return rc; } void cil_destroy_mls(struct cil_mls *mls) { free(mls); } int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) { struct cil_args_build *args = NULL; struct cil_tree_node *ast_current = NULL; struct cil_db *db = NULL; struct cil_tree_node *ast_node = NULL; struct cil_tree_node *macro = NULL; struct cil_tree_node *boolif = NULL; struct cil_tree_node *tunif = NULL; struct cil_tree_node *in = NULL; int rc = SEPOL_ERR; if (parse_current == NULL || finished == NULL || extra_args == NULL) { goto exit; } args = extra_args; ast_current = args->ast; db = args->db; macro = args->macro; boolif = args->boolif; tunif = args->tunif; in = args->in; if (parse_current->parent->cl_head != parse_current) { /* ignore anything that isn't following a parenthesis */ rc = SEPOL_OK; goto exit; } else if (parse_current->data == NULL) { /* the only time parenthsis can immediately following parenthesis is if * the parent is the root node */ if (parse_current->parent->parent == NULL) { rc = SEPOL_OK; } else { cil_log(CIL_ERR, "Keyword expected after open parenthesis in line %d of %s\n", parse_current->line, parse_current->path); } goto exit; } if (macro != NULL) { if (parse_current->data == CIL_KEY_MACRO) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Found macro at line %d of %s\n", parse_current->line, parse_current->path); cil_log(CIL_ERR, "Macros cannot be defined within macro statement\n"); goto exit; } if (parse_current->data == CIL_KEY_TUNABLE) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Found tunable at line %d of %s\n", parse_current->line, parse_current->path); cil_log(CIL_ERR, "Tunables cannot be defined within macro statement\n"); goto exit; } if (parse_current->data == CIL_KEY_IN) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Found in at line %d of %s\n", parse_current->line, parse_current->path); cil_log(CIL_ERR, "in-statements cannot be defined within macro statement\n"); goto exit; } } if (boolif != NULL) { if (parse_current->data != CIL_KEY_CONDTRUE && parse_current->data != CIL_KEY_CONDFALSE && parse_current->data != CIL_KEY_AUDITALLOW && parse_current->data != CIL_KEY_TUNABLEIF && parse_current->data != CIL_KEY_ALLOW && parse_current->data != CIL_KEY_DONTAUDIT && parse_current->data != CIL_KEY_TYPETRANSITION && parse_current->data != CIL_KEY_TYPECHANGE && parse_current->data != CIL_KEY_CALL) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Found %s at line %d of %s\n", (char*)parse_current->data, parse_current->line, parse_current->path); if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { cil_log(CIL_ERR, "%s cannot be defined within tunableif statement (treated as a booleanif due to preserve-tunables)\n", (char*)parse_current->data); } else { cil_log(CIL_ERR, "%s cannot be defined within booleanif statement\n", (char*)parse_current->data); } goto exit; } } if (tunif != NULL) { if (parse_current->data == CIL_KEY_TUNABLE) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Found tunable at line %d of %s\n", parse_current->line, parse_current->path); cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); goto exit; } } if (in != NULL) { if (parse_current->data == CIL_KEY_IN) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Found in-statement at line %d of %s\n", parse_current->line, parse_current->path); cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); goto exit; } } cil_tree_node_init(&ast_node); ast_node->parent = ast_current; ast_node->line = parse_current->line; ast_node->path = parse_current->path; if (parse_current->data == CIL_KEY_BLOCK) { rc = cil_gen_block(db, parse_current, ast_node, 0); } else if (parse_current->data == CIL_KEY_BLOCKINHERIT) { rc = cil_gen_blockinherit(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_BLOCKABSTRACT) { rc = cil_gen_blockabstract(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_IN) { rc = cil_gen_in(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_CLASS) { rc = cil_gen_class(db, parse_current, ast_node); // To avoid parsing list of perms again *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSORDER) { rc = cil_gen_classorder(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MAP_CLASS) { rc = cil_gen_map_class(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSMAPPING) { rc = cil_gen_classmapping(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSPERMISSION) { rc = cil_gen_classpermission(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSPERMISSIONSET) { rc = cil_gen_classpermissionset(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_COMMON) { rc = cil_gen_common(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSCOMMON) { rc = cil_gen_classcommon(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_SID) { rc = cil_gen_sid(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SIDCONTEXT) { rc = cil_gen_sidcontext(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SIDORDER) { rc = cil_gen_sidorder(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_USER) { rc = cil_gen_user(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_USERLEVEL) { rc = cil_gen_userlevel(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_USERRANGE) { rc = cil_gen_userrange(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_USERBOUNDS) { rc = cil_gen_bounds(db, parse_current, ast_node, CIL_USER); } else if (parse_current->data == CIL_KEY_USERPREFIX) { rc = cil_gen_userprefix(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_SELINUXUSER) { rc = cil_gen_selinuxuser(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SELINUXUSERDEFAULT) { rc = cil_gen_selinuxuserdefault(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_TYPE) { rc = cil_gen_type(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTE) { rc = cil_gen_typeattribute(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTESET) { rc = cil_gen_typeattributeset(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_TYPEALIAS) { rc = cil_gen_alias(db, parse_current, ast_node, CIL_TYPEALIAS); } else if (parse_current->data == CIL_KEY_TYPEALIASACTUAL) { rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_TYPEALIASACTUAL); } else if (parse_current->data == CIL_KEY_TYPEBOUNDS) { rc = cil_gen_bounds(db, parse_current, ast_node, CIL_TYPE); } else if (parse_current->data == CIL_KEY_TYPEPERMISSIVE) { rc = cil_gen_typepermissive(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_RANGETRANSITION) { rc = cil_gen_rangetransition(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_ROLE) { rc = cil_gen_role(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_USERROLE) { rc = cil_gen_userrole(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLETYPE) { rc = cil_gen_roletype(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLETRANSITION) { rc = cil_gen_roletransition(parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLEALLOW) { rc = cil_gen_roleallow(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTE) { rc = cil_gen_roleattribute(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTESET) { rc = cil_gen_roleattributeset(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_ROLEBOUNDS) { rc = cil_gen_bounds(db, parse_current, ast_node, CIL_ROLE); } else if (parse_current->data == CIL_KEY_BOOL) { rc = cil_gen_bool(db, parse_current, ast_node, CIL_FALSE); } else if (parse_current->data == CIL_KEY_BOOLEANIF) { rc = cil_gen_boolif(db, parse_current, ast_node, CIL_FALSE); } else if(parse_current->data == CIL_KEY_TUNABLE) { if (db->preserve_tunables) { rc = cil_gen_bool(db, parse_current, ast_node, CIL_TRUE); } else { rc = cil_gen_tunable(db, parse_current, ast_node); } } else if (parse_current->data == CIL_KEY_TUNABLEIF) { if (db->preserve_tunables) { rc = cil_gen_boolif(db, parse_current, ast_node, CIL_TRUE); } else { rc = cil_gen_tunif(db, parse_current, ast_node); } } else if (parse_current->data == CIL_KEY_CONDTRUE) { rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDTRUE); } else if (parse_current->data == CIL_KEY_CONDFALSE) { rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDFALSE); } else if (parse_current->data == CIL_KEY_ALLOW) { rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_ALLOWED); // So that the object and perms lists do not get parsed again *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_AUDITALLOW) { rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_AUDITALLOW); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DONTAUDIT) { rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_DONTAUDIT); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_NEVERALLOW) { rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_NEVERALLOW); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_TYPETRANSITION) { rc = cil_gen_typetransition(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_TYPECHANGE) { rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_CHANGE); } else if (parse_current->data == CIL_KEY_TYPEMEMBER) { rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_MEMBER); } else if (parse_current->data == CIL_KEY_SENSITIVITY) { rc = cil_gen_sensitivity(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_SENSALIAS) { rc = cil_gen_alias(db, parse_current, ast_node, CIL_SENSALIAS); } else if (parse_current->data == CIL_KEY_SENSALIASACTUAL) { rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_SENSALIASACTUAL); } else if (parse_current->data == CIL_KEY_CATEGORY) { rc = cil_gen_category(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_CATALIAS) { rc = cil_gen_alias(db, parse_current, ast_node, CIL_CATALIAS); } else if (parse_current->data == CIL_KEY_CATALIASACTUAL) { rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_CATALIASACTUAL); } else if (parse_current->data == CIL_KEY_CATSET) { rc = cil_gen_catset(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CATORDER) { rc = cil_gen_catorder(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SENSITIVITYORDER) { rc = cil_gen_sensitivityorder(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SENSCAT) { rc = cil_gen_senscat(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_LEVEL) { rc = cil_gen_level(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_LEVELRANGE) { rc = cil_gen_levelrange(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CONSTRAIN) { rc = cil_gen_constrain(db, parse_current, ast_node, CIL_CONSTRAIN); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MLSCONSTRAIN) { rc = cil_gen_constrain(db, parse_current, ast_node, CIL_MLSCONSTRAIN); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_VALIDATETRANS) { rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_VALIDATETRANS); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MLSVALIDATETRANS) { rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_MLSVALIDATETRANS); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CONTEXT) { rc = cil_gen_context(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_FILECON) { rc = cil_gen_filecon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PORTCON) { rc = cil_gen_portcon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_NODECON) { rc = cil_gen_nodecon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_GENFSCON) { rc = cil_gen_genfscon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_NETIFCON) { rc = cil_gen_netifcon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PIRQCON) { rc = cil_gen_pirqcon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_IOMEMCON) { rc = cil_gen_iomemcon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_IOPORTCON) { rc = cil_gen_ioportcon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PCIDEVICECON) { rc = cil_gen_pcidevicecon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_FSUSE) { rc = cil_gen_fsuse(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MACRO) { rc = cil_gen_macro(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_CALL) { rc = cil_gen_call(db, parse_current, ast_node); *finished = 1; } else if (parse_current->data == CIL_KEY_POLICYCAP) { rc = cil_gen_policycap(db, parse_current, ast_node); *finished = 1; } else if (parse_current->data == CIL_KEY_OPTIONAL) { rc = cil_gen_optional(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_IPADDR) { rc = cil_gen_ipaddr(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_DEFAULTUSER) { rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTUSER); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DEFAULTROLE) { rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTROLE); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DEFAULTTYPE) { rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTTYPE); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DEFAULTRANGE) { rc = cil_gen_defaultrange(parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_HANDLEUNKNOWN) { rc = cil_gen_handleunknown(parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MLS) { rc = cil_gen_mls(parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; } else { cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char*)parse_current->data); rc = SEPOL_ERR; } if (rc == SEPOL_OK) { if (ast_current->cl_head == NULL) { if (ast_current->flavor == CIL_MACRO) { args->macro = ast_current; } if (ast_current->flavor == CIL_BOOLEANIF) { args->boolif = ast_current; } if (ast_current->flavor == CIL_TUNABLEIF) { args->tunif = ast_current; } if (ast_current->flavor == CIL_IN) { args->in = ast_current; } ast_current->cl_head = ast_node; } else { ast_current->cl_tail->next = ast_node; } ast_current->cl_tail = ast_node; ast_current = ast_node; args->ast = ast_current; } else { cil_tree_node_destroy(&ast_node); } exit: return rc; } int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) { int rc = SEPOL_ERR; struct cil_tree_node *ast = NULL; struct cil_args_build *args = NULL; if (extra_args == NULL) { goto exit; } args = extra_args; ast = args->ast; if (ast->flavor == CIL_ROOT) { rc = SEPOL_OK; goto exit; } args->ast = ast->parent; if (ast->flavor == CIL_MACRO) { args->macro = NULL; } if (ast->flavor == CIL_BOOLEANIF) { args->boolif = NULL; } if (ast->flavor == CIL_TUNABLEIF) { args->tunif = NULL; } if (ast->flavor == CIL_IN) { args->in = 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 useage (of which the parse tree uses alot), start // deleting the parts we don't need now. cil_tree_children_destroy(parse_current->parent); return SEPOL_OK; exit: return rc; } int cil_build_ast(__attribute__((unused)) 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.macro = NULL; extra_args.boolif = NULL; extra_args.tunif = NULL; extra_args.in = NULL; rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args); if (rc != SEPOL_OK) { goto exit; } return SEPOL_OK; exit: return rc; } libsepol-2.4/cil/src/cil_build_ast.h000066400000000000000000000407621246370572200175150ustar00rootroot00000000000000/* * 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_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_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_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_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_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_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_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 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_ */ libsepol-2.4/cil/src/cil_copy_ast.c000066400000000000000000001307761246370572200173700ustar00rootroot00000000000000/* * 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" struct cil_args_copy { 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; } 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) { struct cil_block *new; cil_block_init(&new); *copy = new; } else { *copy = datum;; } 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; *copy = new; return SEPOL_OK; } 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_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; 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_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, void *data, void **copy, symtab_t *symtab) { struct cil_type *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_type *new; cil_type_init(&new); *copy = new; } else { *copy = datum; } 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, void *data, void **copy, symtab_t *symtab) { struct cil_typeattribute *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_typeattribute *new; cil_typeattribute_init(&new); *copy = new; } else { *copy = datum; } 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; } 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; } 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; } 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; } 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; } int cil_copy_avrule(__attribute__((unused)) 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->rule_kind = orig->rule_kind; new->src_str = orig->src_str; new->tgt_str = orig->tgt_str; cil_copy_classperms_list(orig->classperms, &new->classperms); *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; } 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_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; } 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; 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; } 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) { struct cil_macro *new; cil_macro_init(&new); cil_copy_list(orig->params, &new->params); *copy = new; } else { struct cil_list_item *curr_orig = NULL; struct cil_list_item *curr_new = NULL; struct cil_param *param_orig = NULL; struct cil_param *param_new = NULL; if (((struct cil_macro*)datum)->params != NULL) { curr_new = ((struct cil_macro*)datum)->params->head; } if (orig->params != NULL) { curr_orig = orig->params->head; } if (curr_orig != NULL && curr_new != NULL) { while (curr_orig != NULL) { if (curr_new == NULL) { goto exit; } param_orig = (struct cil_param*)curr_orig->data; param_new = (struct cil_param*)curr_new->data; if (param_orig->str != param_new->str) { goto exit; } else if (param_orig->flavor != param_new->flavor) { goto exit; } curr_orig = curr_orig->next; curr_new = curr_new->next; } if (curr_new != NULL) { goto exit; } } else if (!(curr_orig == NULL && curr_new == NULL)) { goto exit; } *copy = datum; } return SEPOL_OK; exit: cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n"); return SEPOL_ERR; } int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) { struct cil_optional *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_optional *new; cil_optional_init(&new); *copy = new; } else { *copy = datum; } 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; } 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; } 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; } 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; } 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; } 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; } 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; } 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; } int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) 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; struct cil_param *param = 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; 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: 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_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_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: copy_func = &cil_copy_avrule; 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_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_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; 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) { cil_tree_node_init(&new); new->parent = parent; new->line = orig->line; new->path = orig->path; new->flavor = orig->flavor; new->data = data; if (orig->flavor >= CIL_MIN_DECLARATIVE) { rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new); namespace = new; while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) { namespace = namespace->parent; } if (namespace->flavor == CIL_MACRO) { struct cil_macro *macro = namespace->data; struct cil_list *param_list = macro->params; if (param_list != NULL) { struct cil_list_item *item; cil_list_for_each(item, param_list) { param = item->data; if (param->flavor == new->flavor) { if (param->str == ((struct cil_symtab_datum*)new->data)->name) { cil_log(CIL_ERR, "%s %s shadows a macro parameter (%s line:%d)\n", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name, orig->path, orig->line); cil_log(CIL_ERR, "Note: macro declaration (%s line:%d)\n", namespace->path, namespace->line); rc = SEPOL_ERR; goto exit; } } } } } } 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 { goto exit; } return SEPOL_OK; exit: cil_tree_node_destroy(&new); return rc; } 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.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_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc); goto exit; } return SEPOL_OK; exit: return rc; } libsepol-2.4/cil/src/cil_copy_ast.h000066400000000000000000000202351246370572200173610ustar00rootroot00000000000000/* * 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_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_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 libsepol-2.4/cil/src/cil_flavor.h000066400000000000000000000101721246370572200170300ustar00rootroot00000000000000/* * 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_USERLEVEL, CIL_USERRANGE, CIL_USERBOUNDS, CIL_SELINUXUSER, CIL_SELINUXUSERDEFAULT, CIL_ROLEATTRIBUTESET, CIL_ROLETYPE, CIL_ROLEBOUNDS, CIL_TYPEATTRIBUTESET, CIL_TYPEALIASACTUAL, CIL_TYPEBOUNDS, CIL_TYPEPERMISSIVE, CIL_SENSALIASACTUAL, CIL_SENSITIVITYORDER, CIL_SENSCAT, CIL_CATALIASACTUAL, CIL_CATORDER, CIL_SIDORDER, CIL_ROLEALLOW, CIL_AVRULE, 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_DEFAULTUSER, CIL_DEFAULTROLE, CIL_DEFAULTTYPE, CIL_DEFAULTRANGE, CIL_HANDLEUNKNOWN, CIL_MLS, /* * 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_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, }; #endif /* CIL_FLAVOR_H_ */ libsepol-2.4/cil/src/cil_fqn.c000066400000000000000000000125141246370572200163200ustar00rootroot00000000000000/* * 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_strpool.h" struct cil_args_qualify { char fqparent[CIL_MAX_NAME_LENGTH]; int len; }; int __cil_fqn_qualify_last_child_helper(struct cil_tree_node *node, void *extra_args) { struct cil_args_qualify *args = NULL; struct cil_symtab_datum *datum = NULL; int rc = SEPOL_ERR; if (node == NULL || extra_args == NULL) { rc = SEPOL_ERR; goto exit; } if (node->parent->flavor != CIL_BLOCK) { rc = SEPOL_OK; goto exit; } datum = node->parent->data; args = extra_args; args->len -= (strlen(datum->name) + 1); args->fqparent[args->len] = '\0'; return SEPOL_OK; exit: return rc; } int __cil_fqn_qualify_first_child_helper(struct cil_tree_node *node, void *extra_args) { struct cil_args_qualify *args = NULL; struct cil_symtab_datum *datum = NULL; int rc = SEPOL_ERR; if (node == NULL || extra_args == NULL) { rc = SEPOL_ERR; goto exit; } if (node->parent->flavor != CIL_BLOCK) { rc = SEPOL_OK; goto exit; } args = extra_args; datum = node->parent->data; if (args->len + strlen(datum->name) + 1 >= CIL_MAX_NAME_LENGTH) { cil_log(CIL_INFO, "Fully qualified name too long at line %d of %s\n", node->line, node->path); rc = SEPOL_ERR; goto exit; } strcat(args->fqparent, datum->name); strcat(args->fqparent, "."); args->len += (strlen(datum->name) + 1); return SEPOL_OK; exit: return rc; } int __cil_fqn_qualify_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) { struct cil_args_qualify *args = NULL; struct cil_symtab_datum *datum = NULL; char *fqn = NULL; int newlen = 0; int rc = SEPOL_ERR; if (node == NULL || finished == NULL || extra_args == NULL) { goto exit; } if (node->flavor < CIL_MIN_DECLARATIVE || node->flavor == CIL_PERM || node->flavor == CIL_MAP_PERM) { rc = SEPOL_OK; goto exit; } args = extra_args; datum = node->data; switch (node->flavor) { case CIL_OPTIONAL: if (datum->state == CIL_STATE_DISABLED) { *finished = CIL_TREE_SKIP_HEAD; } break; case CIL_MACRO: *finished = CIL_TREE_SKIP_HEAD; break; case CIL_BLOCK: if (((struct cil_block *)datum)->is_abstract == CIL_TRUE) { *finished = CIL_TREE_SKIP_HEAD; } break; case CIL_STRING: case CIL_NAME: /* Strings don't change */ break; case CIL_TYPEATTRIBUTE: case CIL_ROLEATTRIBUTE: case CIL_BOOL: case CIL_CAT: case CIL_CATALIAS: case CIL_CATSET: case CIL_CLASS: case CIL_MAP_CLASS: case CIL_CLASSPERMISSION: case CIL_COMMON: case CIL_CONTEXT: case CIL_IPADDR: case CIL_LEVEL: case CIL_LEVELRANGE: case CIL_POLICYCAP: case CIL_ROLE: case CIL_SENS: case CIL_SENSALIAS: case CIL_SID: case CIL_TUNABLE: case CIL_TYPE: case CIL_TYPEALIAS: case CIL_USER: if (node != ((struct cil_symtab_datum*)node->data)->nodes->head->data) { break; } if (args->len == 0) { rc = SEPOL_OK; goto exit; } newlen = args->len + strlen(datum->name); if (newlen >= CIL_MAX_NAME_LENGTH) { cil_log(CIL_INFO, "Fully qualified name too long at line %d of %s\n", node->line, node->path); rc = SEPOL_ERR; goto exit; } fqn = cil_malloc(newlen + 1); strcpy(fqn, args->fqparent); strcat(fqn, datum->name); datum->name = cil_strpool_add(fqn); free(fqn); break; default: rc = SEPOL_ERR; goto exit; } return SEPOL_OK; exit: return rc; } int cil_fqn_qualify(struct cil_tree_node *root) { struct cil_args_qualify extra_args; int rc = SEPOL_ERR; extra_args.fqparent[0] = '\0'; extra_args.len = 0; rc = cil_tree_walk(root, __cil_fqn_qualify_node_helper, __cil_fqn_qualify_first_child_helper, __cil_fqn_qualify_last_child_helper, &extra_args); if (rc != SEPOL_OK) { goto exit; } return SEPOL_OK; exit: return rc; } libsepol-2.4/cil/src/cil_fqn.h000066400000000000000000000033561246370572200163310ustar00rootroot00000000000000/* * 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); #endif /* CIL_FQN_H_ */ libsepol-2.4/cil/src/cil_internal.h000066400000000000000000000555041246370572200173630ustar00rootroot00000000000000/* * 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 "cil_flavor.h" #include "cil_tree.h" #include "cil_symtab.h" #include "cil_mem.h" #define CIL_MAX_NAME_LENGTH 2048 enum cil_pass { CIL_PASS_INIT = 0, CIL_PASS_TIF, CIL_PASS_IN, CIL_PASS_BLKIN, CIL_PASS_BLKABS, CIL_PASS_MACRO, 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 */ 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_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_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_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_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_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_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_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; /* 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_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 int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM]; #define CIL_CLASS_SYM_SIZE 256 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 *portcon; struct cil_sort *pirqcon; struct cil_sort *iomemcon; struct cil_sort *ioportcon; struct cil_sort *pcidevicecon; struct cil_sort *fsuse; struct cil_list *userprefixes; struct cil_list *selinuxusers; struct cil_list *names; int num_cats; int num_types; int num_roles; struct cil_type **val_to_type; struct cil_role **val_to_role; int disable_dontaudit; int disable_neverallow; int preserve_tunables; int handle_unknown; int mls; }; 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_blockinherit { char *block_str; }; struct cil_blockabstract { char *block_str; }; struct cil_in { symtab_t symtab[CIL_SYM_NUM]; 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; struct cil_list *roles; struct cil_level *dftlevel; struct cil_levelrange *range; }; struct cil_userrole { char *user_str; struct cil_user *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; }; struct cil_typeattribute { struct cil_symtab_datum datum; struct cil_list *expr_list; ebitmap_t *types; int used; // whether or not this typeattribute was used and should be added to the binary }; struct cil_typeattributeset { char *attr_str; struct cil_list *str_expr; struct cil_list *datum_expr; }; 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 { uint32_t rule_kind; char *src_str; void *src; /* type, alias, or attribute */ char *tgt_str; void *tgt; /* type, alias, or attribute */ struct cil_list *classperms; }; #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_FILE = 1, CIL_FILECON_DIR, CIL_FILECON_CHAR, CIL_FILECON_BLOCK, CIL_FILECON_SOCKET, CIL_FILECON_PIPE, CIL_FILECON_SYMLINK, CIL_FILECON_ANY }; 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 }; 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; 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_pirqcon { uint32_t pirq; char *context_str; struct cil_context *context; }; struct cil_iomemcon { uint32_t iomem_low; uint32_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; }; /* 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, }; /* 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; }; 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, sepol_policydb_t *sepol_db, char **out, size_t *size); int cil_selinuxusers_to_string(struct cil_db *db, sepol_policydb_t *sepol_db, char **out, size_t *size); int cil_filecons_to_string(struct cil_db *db, sepol_policydb_t *sepol_db, char **out, size_t *size); void cil_symtab_array_init(symtab_t symtab[], 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); 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_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_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_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_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_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); #endif libsepol-2.4/cil/src/cil_lexer.h000066400000000000000000000037401246370572200166610ustar00rootroot00000000000000/* * 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 END_OF_FILE 6 #define UNKNOWN 7 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_ */ libsepol-2.4/cil/src/cil_lexer.l000066400000000000000000000053671246370572200166740ustar00rootroot00000000000000/* * 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]*\" comment ;[^\n]* %% {newline} line++; {comment} value=yytext; return COMMENT; "(" value=yytext; return OPAREN; ")" value=yytext; return CPAREN; {symbol} value=yytext; return SYMBOL; {white} //cil_log(CIL_INFO, "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; } libsepol-2.4/cil/src/cil_list.c000066400000000000000000000122531246370572200165070ustar00rootroot00000000000000/* * 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_flavor.h" #include "cil_log.h" #include "cil_mem.h" __attribute__((noreturn)) void cil_list_error(const char* msg) { cil_log(CIL_ERR, "%s\n",msg); 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) { if (*list == NULL) { return; } struct cil_list_item *item = (*list)->head; struct cil_list_item *next = NULL; while (item != NULL) { 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; } libsepol-2.4/cil/src/cil_list.h000066400000000000000000000052221246370572200165120ustar00rootroot00000000000000/* * 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); 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); #endif libsepol-2.4/cil/src/cil_log.c000066400000000000000000000046101246370572200163130ustar00rootroot00000000000000/* * 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; void cil_default_log_handler(__attribute__((unused)) int lvl, char *msg) { fprintf(stderr, "%s", msg); } void (*cil_log_handler)(int lvl, char *msg) = &cil_default_log_handler; void cil_set_log_handler(void (*handler)(int lvl, char *msg)) { cil_log_handler = handler; } __attribute__ ((format (printf, 2, 3))) void cil_log(enum cil_log_level lvl, const char *msg, ...) { if (cil_log_level >= lvl) { char buff[MAX_LOG_SIZE]; va_list args; va_start(args, msg); vsnprintf(buff, MAX_LOG_SIZE, msg, args); va_end(args); (*cil_log_handler)(cil_log_level, buff); } } void cil_set_log_level(enum cil_log_level lvl) { cil_log_level = lvl; } libsepol-2.4/cil/src/cil_log.h000066400000000000000000000034571246370572200163300ustar00rootroot00000000000000/* * 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 #define MAX_LOG_SIZE 512 __attribute__ ((format(printf, 2, 3))) void cil_log(enum cil_log_level lvl, const char *msg, ...); #endif // CIL_LOG_H_ libsepol-2.4/cil/src/cil_mem.c000066400000000000000000000052221246370572200163100ustar00rootroot00000000000000/* * 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_log.h" __attribute__((noreturn)) void cil_default_mem_error_handler(void) { cil_log(CIL_ERR, "Failed to allocate memory\n"); exit(1); } void (*cil_mem_error_handler)(void) = &cil_default_mem_error_handler; void cil_set_mem_error_handler(void (*handler)(void)) { cil_mem_error_handler = handler; } void *cil_malloc(size_t size) { void *mem = malloc(size); if (mem == NULL){ if (size == 0) { return NULL; } (*cil_mem_error_handler)(); } return mem; } void *cil_calloc(size_t num_elements, size_t element_size) { void *mem = calloc(num_elements, element_size); if (mem == NULL){ (*cil_mem_error_handler)(); } return mem; } void *cil_realloc(void *ptr, size_t size) { void *mem = realloc(ptr, size); if (mem == NULL){ if (size == 0) { return NULL; } (*cil_mem_error_handler)(); } return mem; } char *cil_strdup(const char *str) { char *mem = NULL; if (str == NULL) { return NULL; } mem = strdup(str); if (mem == NULL) { (*cil_mem_error_handler)(); } return mem; } libsepol-2.4/cil/src/cil_mem.h000066400000000000000000000036411246370572200163200ustar00rootroot00000000000000/* * 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); void (*cil_mem_error_handler)(void); #endif /* CIL_MEM_H_ */ libsepol-2.4/cil/src/cil_parser.c000066400000000000000000000077331246370572200170370ustar00rootroot00000000000000/* * 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_strpool.h" int cil_parser(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 *item = NULL; struct cil_tree_node *current = NULL; struct token tok; cil_lexer_setup(buffer, size); tree = *parse_tree; current = tree->root; do { cil_lexer_next(&tok); switch (tok.type) { case OPAREN: paren_count++; cil_tree_node_init(&node); node->parent = current; node->flavor = CIL_NODE; node->line = tok.line; node->path = path; if (current->cl_head == NULL) { current->cl_head = node; } else { current->cl_tail->next = node; } current->cl_tail = node; 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); return SEPOL_ERR; } current = current->parent; break; case SYMBOL: case QSTRING: if (paren_count == 0) { cil_log(CIL_ERR, "Symbol not inside parenthesis at line %d of %s\n", tok.line, path); return SEPOL_ERR; } cil_tree_node_init(&item); item->parent = current; if (tok.type == QSTRING) { tok.value[strlen(tok.value) - 1] = '\0'; item->data = cil_strpool_add(tok.value + 1); } else { item->data = cil_strpool_add(tok.value); } item->flavor = CIL_NODE; item->line = tok.line; item->path = path; if (current->cl_head == NULL) { current->cl_head = item; } else { current->cl_tail->next = item; } current->cl_tail = item; break; 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); return SEPOL_ERR; } break; case COMMENT: // ignore break; case UNKNOWN: cil_log(CIL_ERR, "Invalid token '%s' at line %d of %s\n", tok.value, tok.line, path); return SEPOL_ERR; default: cil_log(CIL_ERR, "Unknown token type '%d' at line %d of %s\n", tok.type, tok.line, path); return SEPOL_ERR; } } while (tok.type != END_OF_FILE); cil_lexer_destroy(); *parse_tree = tree; return SEPOL_OK; } libsepol-2.4/cil/src/cil_parser.h000066400000000000000000000034031246370572200170320ustar00rootroot00000000000000/* * 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(char *path, char *buffer, uint32_t size, struct cil_tree **parse_tree); #endif /* CIL_PARSER_H_ */ libsepol-2.4/cil/src/cil_policy.c000066400000000000000000001204541246370572200170360ustar00rootroot00000000000000/* * 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 "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_policy.h" #include "cil_symtab.h" #include "cil_strpool.h" #define SEPOL_DONE 555 #define CLASS_DECL 0 #define ISIDS 1 #define COMMONS 2 #define CLASSES 3 #define INTERFACES 4 #define SENS 5 #define CATS 6 #define LEVELS 7 #define CONSTRAINS 8 #define TYPEATTRTYPES 9 #define ALIASES 10 #define ALLOWS 11 #define CONDS 12 #define USERROLES 13 #define SIDS 14 #define NETIFCONS 15 #define BUFFER 1024 #define NUM_POLICY_FILES 16 struct cil_args_genpolicy { struct cil_list *users; struct cil_list *sens; struct cil_list *cats; FILE **file_arr; }; struct cil_args_booleanif { FILE **file_arr; uint32_t *file_index; }; int cil_expr_to_policy(FILE **file_arr, uint32_t file_index, struct cil_list *expr); int cil_combine_policy(FILE **file_arr, FILE *policy_file) { char temp[BUFFER]; int i, rc, rc_read, rc_write; for(i=0; i rc_write) { rc = fwrite(temp+rc_write, 1, rc_read-rc_write, policy_file); rc_write += rc; if (rc == 0 && ferror(file_arr[i])) { cil_log(CIL_ERR, "Error writing to policy.conf\n"); return SEPOL_ERR; } } } } return SEPOL_OK; } int cil_portcon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i=0; icount; i++) { struct cil_portcon *portcon = (struct cil_portcon*)sort->array[i]; fprintf(file_arr[NETIFCONS], "portcon "); if (portcon->proto == CIL_PROTOCOL_UDP) { fprintf(file_arr[NETIFCONS], "udp "); } else if (portcon->proto == CIL_PROTOCOL_TCP) { fprintf(file_arr[NETIFCONS], "tcp "); } fprintf(file_arr[NETIFCONS], "%d ", portcon->port_low); fprintf(file_arr[NETIFCONS], "%d ", portcon->port_high); cil_context_to_policy(file_arr, NETIFCONS, portcon->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_genfscon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i=0; icount; i++) { struct cil_genfscon *genfscon = (struct cil_genfscon*)sort->array[i]; fprintf(file_arr[NETIFCONS], "genfscon %s ", genfscon->fs_str); fprintf(file_arr[NETIFCONS], "%s ", genfscon->path_str); cil_context_to_policy(file_arr, NETIFCONS, genfscon->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_netifcon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i=0; icount; i++) { struct cil_netifcon *netifcon = (struct cil_netifcon*)sort->array[i]; fprintf(file_arr[NETIFCONS], "netifcon %s ", netifcon->interface_str); cil_context_to_policy(file_arr, NETIFCONS, netifcon->if_context); fprintf(file_arr[NETIFCONS], " "); cil_context_to_policy(file_arr, NETIFCONS, netifcon->packet_context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_nodecon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; int rc = SEPOL_ERR; for (i=0; icount; i++) { struct cil_nodecon *nodecon = (struct cil_nodecon*)sort->array[i]; char *buf = NULL; errno = 0; if (nodecon->addr->family == AF_INET) { buf = cil_malloc(INET_ADDRSTRLEN); inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v4, buf, INET_ADDRSTRLEN); } else if (nodecon->addr->family == AF_INET6) { buf = cil_malloc(INET6_ADDRSTRLEN); inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v6, buf, INET6_ADDRSTRLEN); } if (errno != 0) { cil_log(CIL_INFO, "Failed to convert ip address to string\n"); rc = SEPOL_ERR; goto exit; } fprintf(file_arr[NETIFCONS], "nodecon %s ", buf); free(buf); if (nodecon->mask->family == AF_INET) { buf = cil_malloc(INET_ADDRSTRLEN); inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v4, buf, INET_ADDRSTRLEN); } else if (nodecon->mask->family == AF_INET6) { buf = cil_malloc(INET6_ADDRSTRLEN); inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v6, buf, INET6_ADDRSTRLEN); } if (errno != 0) { cil_log(CIL_INFO, "Failed to convert mask to string\n"); rc = SEPOL_ERR; goto exit; } fprintf(file_arr[NETIFCONS], "%s ", buf); free(buf); cil_context_to_policy(file_arr, NETIFCONS, nodecon->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; exit: return rc; } int cil_pirqcon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i = 0; i < sort->count; i++) { struct cil_pirqcon *pirqcon = (struct cil_pirqcon*)sort->array[i]; fprintf(file_arr[NETIFCONS], "pirqcon %d ", pirqcon->pirq); cil_context_to_policy(file_arr, NETIFCONS, pirqcon->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_iomemcon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i = 0; i < sort->count; i++) { struct cil_iomemcon *iomemcon = (struct cil_iomemcon*)sort->array[i]; fprintf(file_arr[NETIFCONS], "iomemcon %d-%d ", iomemcon->iomem_low, iomemcon->iomem_high); cil_context_to_policy(file_arr, NETIFCONS, iomemcon->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_ioportcon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i = 0; i < sort->count; i++) { struct cil_ioportcon *ioportcon = (struct cil_ioportcon*)sort->array[i]; fprintf(file_arr[NETIFCONS], "ioportcon %d-%d ", ioportcon->ioport_low, ioportcon->ioport_high); cil_context_to_policy(file_arr, NETIFCONS, ioportcon->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_pcidevicecon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i = 0; i < sort->count; i++) { struct cil_pcidevicecon *pcidevicecon = (struct cil_pcidevicecon*)sort->array[i]; fprintf(file_arr[NETIFCONS], "pcidevicecon %d ", pcidevicecon->dev); cil_context_to_policy(file_arr, NETIFCONS, pcidevicecon->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_fsuse_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; for (i=0; icount; i++) { struct cil_fsuse *fsuse = (struct cil_fsuse*)sort->array[i]; if (fsuse->type == CIL_FSUSE_XATTR) { fprintf(file_arr[NETIFCONS], "fs_use_xattr "); } else if (fsuse->type == CIL_FSUSE_TASK) { fprintf(file_arr[NETIFCONS], "fs_use_task "); } else if (fsuse->type == CIL_FSUSE_TRANS) { fprintf(file_arr[NETIFCONS], "fs_use_trans "); } else { return SEPOL_ERR; } fprintf(file_arr[NETIFCONS], "%s ", fsuse->fs_str); cil_context_to_policy(file_arr, NETIFCONS, fsuse->context); fprintf(file_arr[NETIFCONS], ";\n"); } return SEPOL_OK; } int cil_multimap_insert(struct cil_list *list, struct cil_symtab_datum *key, struct cil_symtab_datum *value, uint32_t key_flavor, uint32_t val_flavor) { struct cil_list_item *curr_key; struct cil_multimap_item *new_data; if (list == NULL || key == NULL) { return SEPOL_ERR; } cil_list_for_each(curr_key, list) { struct cil_multimap_item *curr_multimap_item = curr_key->data; if (curr_multimap_item != NULL) { if (curr_multimap_item->key != NULL && curr_multimap_item->key == key) { struct cil_list_item *curr_value; cil_list_for_each(curr_value, curr_multimap_item->values) { if (curr_value == (struct cil_list_item*)value) { return SEPOL_OK;; } } cil_list_append(curr_multimap_item->values, val_flavor, value); } } else { cil_log(CIL_INFO, "No data in list item\n"); return SEPOL_ERR; } } new_data = cil_malloc(sizeof(*new_data)); new_data->key = key; cil_list_init(&new_data->values, CIL_LIST_ITEM); if (value != NULL) { cil_list_append(new_data->values, val_flavor, value); } cil_list_append(list, key_flavor, new_data); return SEPOL_OK; } int cil_userrole_to_policy(FILE **file_arr, struct cil_list *userroles) { struct cil_list_item *current_user; if (userroles == NULL) { return SEPOL_OK; } cil_list_for_each(current_user, userroles) { struct cil_multimap_item *user_multimap_item = current_user->data; struct cil_list_item *current_role; if (user_multimap_item->values->head == NULL) { cil_log(CIL_INFO, "No roles associated with user %s\n", user_multimap_item->key->name); return SEPOL_ERR; } fprintf(file_arr[USERROLES], "user %s roles {", user_multimap_item->key->name); cil_list_for_each(current_role, user_multimap_item->values) { fprintf(file_arr[USERROLES], " %s", ((struct cil_role*)current_role->data)->datum.name); } fprintf(file_arr[USERROLES], " };\n"); } return SEPOL_OK; } int cil_cat_to_policy(FILE **file_arr, struct cil_list *cats) { struct cil_list_item *curr_cat; if (cats == NULL) { return SEPOL_OK; } cil_list_for_each(curr_cat, cats) { struct cil_multimap_item *cat_multimap_item = curr_cat->data; fprintf(file_arr[CATS], "category %s", cat_multimap_item->key->name); if (cat_multimap_item->values->head == NULL) { fprintf(file_arr[CATS], ";\n"); } else { struct cil_list_item *curr_catalias; fprintf(file_arr[CATS], " alias"); cil_list_for_each(curr_catalias, cat_multimap_item->values) { fprintf(file_arr[CATS], " %s", ((struct cil_cat*)curr_catalias->data)->datum.name); } fprintf(file_arr[CATS], ";\n"); } } return SEPOL_OK; } int cil_sens_to_policy(FILE **file_arr, struct cil_list *sens) { struct cil_list_item *curr_sens; if (sens == NULL) { return SEPOL_OK; } cil_list_for_each(curr_sens, sens) { struct cil_multimap_item *sens_multimap_item = curr_sens->data; fprintf(file_arr[SENS], "sensitivity %s", sens_multimap_item->key->name); if (sens_multimap_item->values->head == NULL) fprintf(file_arr[SENS], ";\n"); else { struct cil_list_item *curr_sensalias; fprintf(file_arr[SENS], " alias"); cil_list_for_each(curr_sensalias, sens_multimap_item->values) { fprintf(file_arr[SENS], " %s", ((struct cil_sens*)curr_sensalias->data)->datum.name); } fprintf(file_arr[SENS], ";\n"); } } return SEPOL_OK; } void cil_cats_to_policy(FILE **file_arr, uint32_t file_index, struct cil_cats *cats) { cil_expr_to_policy(file_arr, file_index, cats->datum_expr); } void cil_level_to_policy(FILE **file_arr, uint32_t file_index, struct cil_level *level) { char *sens_str = level->sens->datum.name; fprintf(file_arr[file_index], "%s", sens_str); if (level->cats != NULL) { fprintf(file_arr[file_index], ":"); cil_cats_to_policy(file_arr, file_index, level->cats); } } void cil_levelrange_to_policy(FILE **file_arr, uint32_t file_index, struct cil_levelrange *lvlrange) { struct cil_level *low = lvlrange->low; struct cil_level *high = lvlrange->high; cil_level_to_policy(file_arr, file_index, low); fprintf(file_arr[file_index], "-"); cil_level_to_policy(file_arr, file_index, high); } void cil_context_to_policy(FILE **file_arr, uint32_t file_index, struct cil_context *context) { char *user_str = ((struct cil_symtab_datum*)context->user)->name; char *role_str = ((struct cil_symtab_datum*)context->role)->name; char *type_str = ((struct cil_symtab_datum*)context->type)->name; struct cil_levelrange *lvlrange = context->range; fprintf(file_arr[file_index], "%s:%s:%s:", user_str, role_str, type_str); cil_levelrange_to_policy(file_arr, file_index, lvlrange); } void cil_perms_to_policy(FILE **file_arr, uint32_t file_index, struct cil_list *list) { struct cil_list_item *curr; fprintf(file_arr[file_index], " {"); cil_list_for_each(curr, list) { switch (curr->flavor) { case CIL_LIST: cil_perms_to_policy(file_arr, file_index, curr->data); break; case CIL_STRING: fprintf(file_arr[file_index], " %s", (char *)curr->data); break; case CIL_DATUM: fprintf(file_arr[file_index], " %s", ((struct cil_symtab_datum *)curr->data)->name); break; case CIL_OP: { enum cil_flavor op_flavor = *((enum cil_flavor *)curr->data); char *op_str = NULL; 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_XOR: op_str = CIL_KEY_XOR; break; default: cil_log(CIL_ERR, "Unknown operator in expression\n"); break; } fprintf(file_arr[file_index], " %s", op_str); break; } default: cil_log(CIL_ERR, "Unknown flavor in expression\n"); break; } } fprintf(file_arr[file_index], " }"); } void cil_constrain_to_policy_helper(FILE **file_arr, char *kind, struct cil_list *classperms, struct cil_list *expr) { 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) { fprintf(file_arr[CONSTRAINS], "%s %s", kind, cp->class->datum.name); cil_perms_to_policy(file_arr, CONSTRAINS, cp->perms); fprintf(file_arr[CONSTRAINS], "\n\t"); cil_expr_to_policy(file_arr, CONSTRAINS, expr); fprintf(file_arr[CONSTRAINS], ";\n"); } else { /* MAP */ struct cil_list_item *i = NULL; cil_list_for_each(i, cp->perms) { struct cil_perm *cmp = i->data; cil_constrain_to_policy_helper(file_arr, kind, cmp->classperms, expr); } } } else { /* SET */ struct cil_classperms_set *cp_set = curr->data; struct cil_classpermission *cp = cp_set->set; cil_constrain_to_policy_helper(file_arr, kind, cp->classperms, expr); } } } void cil_constrain_to_policy(FILE **file_arr, __attribute__((unused)) uint32_t file_index, struct cil_constrain *cons, enum cil_flavor flavor) { char *kind = NULL; if (flavor == CIL_CONSTRAIN) { kind = CIL_KEY_CONSTRAIN; } else if (flavor == CIL_MLSCONSTRAIN) { kind = CIL_KEY_MLSCONSTRAIN; } cil_constrain_to_policy_helper(file_arr, kind, cons->classperms, cons->datum_expr); } void cil_avrule_to_policy_helper(FILE **file_arr, uint32_t file_index, const char *kind, const char *src, const char *tgt, struct cil_list *classperms) { 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) { fprintf(file_arr[file_index], "%s %s %s: %s", kind, src, tgt, cp->class->datum.name); cil_perms_to_policy(file_arr, file_index, cp->perms); fprintf(file_arr[file_index], ";\n"); } else { /* MAP */ struct cil_list_item *j = NULL; cil_list_for_each(j, cp->perms) { struct cil_perm *cmp = j->data; cil_avrule_to_policy_helper(file_arr, file_index, kind, src, tgt, cmp->classperms); } } } else { /* SET */ struct cil_list_item *j; struct cil_classperms_set *cp_set = i->data; struct cil_classpermission *cp = cp_set->set; cil_list_for_each(j, cp->classperms) { cil_avrule_to_policy_helper(file_arr, file_index, kind, src, tgt, j->data); } } } } int cil_avrule_to_policy(FILE **file_arr, uint32_t file_index, struct cil_avrule *rule) { const char *kind_str = NULL; const char *src_str = DATUM(rule->src)->name; const char *tgt_str = DATUM(rule->tgt)->name; switch (rule->rule_kind) { case CIL_AVRULE_ALLOWED: kind_str = "allow"; break; case CIL_AVRULE_AUDITALLOW: kind_str = "auditallow"; break; case CIL_AVRULE_DONTAUDIT: kind_str = "dontaudit"; break; case CIL_AVRULE_NEVERALLOW: kind_str = "neverallow"; break; default : cil_log(CIL_INFO, "Unknown avrule with kind=%d src=%s tgt=%s\n", rule->rule_kind, src_str, tgt_str); return SEPOL_ERR; } cil_avrule_to_policy_helper(file_arr, file_index, kind_str, src_str, tgt_str, rule->classperms); return SEPOL_OK; } int cil_typerule_to_policy(FILE **file_arr, __attribute__((unused)) uint32_t file_index, struct cil_type_rule *rule) { char *src_str = ((struct cil_symtab_datum*)rule->src)->name; char *tgt_str = ((struct cil_symtab_datum*)rule->tgt)->name; char *obj_str = ((struct cil_symtab_datum*)rule->obj)->name; char *result_str = ((struct cil_symtab_datum*)rule->result)->name; switch (rule->rule_kind) { case CIL_TYPE_TRANSITION: fprintf(file_arr[ALLOWS], "type_transition %s %s : %s %s;\n", src_str, tgt_str, obj_str, result_str); break; case CIL_TYPE_CHANGE: fprintf(file_arr[ALLOWS], "type_change %s %s : %s %s\n;", src_str, tgt_str, obj_str, result_str); break; case CIL_TYPE_MEMBER: fprintf(file_arr[ALLOWS], "type_member %s %s : %s %s;\n", src_str, tgt_str, obj_str, result_str); break; default: cil_log(CIL_INFO, "Unknown type_rule\n"); return SEPOL_ERR; } return SEPOL_OK; } int cil_nametypetransition_to_policy(FILE **file_arr, uint32_t file_index, struct cil_nametypetransition *nametypetrans) { char *src_str = ((struct cil_symtab_datum*)nametypetrans->src)->name; char *tgt_str = ((struct cil_symtab_datum*)nametypetrans->tgt)->name; char *obj_str = ((struct cil_symtab_datum*)nametypetrans->obj)->name; char *result_str = ((struct cil_symtab_datum*)nametypetrans->result)->name; fprintf(file_arr[file_index], "type_transition %s %s : %s %s %s;\n", src_str, tgt_str, obj_str, result_str, nametypetrans->name_str); return SEPOL_OK; } static int cil_expr_to_string(struct cil_list *expr, char **out) { int rc = SEPOL_ERR; struct cil_list_item *curr; char *stack[COND_EXPR_MAXDEPTH] = {}; int pos = 0; int i; cil_list_for_each(curr, expr) { if (pos > COND_EXPR_MAXDEPTH) { rc = SEPOL_ERR; goto exit; } switch (curr->flavor) { case CIL_LIST: rc = cil_expr_to_string(curr->data, &stack[pos]); if (rc != SEPOL_OK) { goto exit; } pos++; break; case CIL_STRING: stack[pos] = curr->data; pos++; break; case CIL_DATUM: stack[pos] = ((struct cil_symtab_datum *)curr->data)->name; pos++; break; case CIL_OP: { int len; char *expr_str; enum cil_flavor op_flavor = *((enum cil_flavor *)curr->data); char *op_str = NULL; if (pos == 0) { rc = SEPOL_ERR; goto exit; } 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_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: cil_log(CIL_ERR, "Unknown operator in expression\n"); goto exit; break; } if (op_flavor == CIL_NOT) { len = strlen(stack[pos-1]) + strlen(op_str) + 4; expr_str = cil_malloc(len); snprintf(expr_str, len, "(%s %s)", op_str, stack[pos-1]); free(stack[pos-1]); stack[pos-1] = NULL; pos--; } else { if (pos < 2) { rc = SEPOL_ERR; goto exit; } len = strlen(stack[pos-1]) + strlen(stack[pos-2]) + strlen(op_str) + 5; expr_str = cil_malloc(len); snprintf(expr_str, len, "(%s %s %s)", stack[pos-1], op_str, stack[pos-2]); free(stack[pos-2]); free(stack[pos-1]); stack[pos-2] = NULL; stack[pos-1] = NULL; pos -= 2; } stack[pos] = expr_str; pos++; break; } case CIL_CONS_OPERAND: { enum cil_flavor operand_flavor = *((enum cil_flavor *)curr->data); char *operand_str = NULL; 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: cil_log(CIL_ERR, "Unknown operand in expression\n"); goto exit; break; } stack[pos] = operand_str; pos++; break; } default: cil_log(CIL_ERR, "Unknown flavor in expression\n"); goto exit; break; } } *out = stack[0]; return SEPOL_OK; exit: for (i = 0; i < pos; i++) { free(stack[i]); } return rc; } int cil_expr_to_policy(FILE **file_arr, uint32_t file_index, struct cil_list *expr) { int rc = SEPOL_ERR; char *str_out; rc = cil_expr_to_string(expr, &str_out); if (rc != SEPOL_OK) { goto out; } fprintf(file_arr[file_index], "%s", str_out); free(str_out); return SEPOL_OK; out: return rc; } int __cil_booleanif_node_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) { int rc = SEPOL_ERR; struct cil_args_booleanif *args; FILE **file_arr; uint32_t *file_index; args = extra_args; file_arr = args->file_arr; file_index = args->file_index; switch (node->flavor) { case CIL_AVRULE: rc = cil_avrule_to_policy(file_arr, *file_index, (struct cil_avrule*)node->data); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "cil_avrule_to_policy failed, rc: %d\n", rc); return rc; } break; case CIL_TYPE_RULE: rc = cil_typerule_to_policy(file_arr, *file_index, (struct cil_type_rule*)node->data); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "cil_typerule_to_policy failed, rc: %d\n", rc); return rc; } break; case CIL_FALSE: fprintf(file_arr[*file_index], "else {\n"); break; case CIL_TRUE: break; default: return SEPOL_ERR; } return SEPOL_OK; } int __cil_booleanif_last_child_helper(struct cil_tree_node *node, void *extra_args) { struct cil_args_booleanif *args; FILE **file_arr; uint32_t *file_index; args = extra_args; file_arr = args->file_arr; file_index = args->file_index; if (node->parent->flavor == CIL_FALSE) { fprintf(file_arr[*file_index], "}\n"); } return SEPOL_OK; } int cil_booleanif_to_policy(FILE **file_arr, uint32_t file_index, struct cil_tree_node *node) { int rc = SEPOL_ERR; struct cil_booleanif *bif = node->data; struct cil_list *expr = bif->datum_expr; struct cil_args_booleanif extra_args; struct cil_tree_node *true_node = NULL; struct cil_tree_node *false_node = NULL; struct cil_condblock *cb = NULL; extra_args.file_arr = file_arr; extra_args.file_index = &file_index;; fprintf(file_arr[file_index], "if "); rc = cil_expr_to_policy(file_arr, file_index, expr); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to write expression\n"); return rc; } if (node->cl_head != NULL && node->cl_head->flavor == CIL_CONDBLOCK) { cb = node->cl_head->data; if (cb->flavor == CIL_CONDTRUE) { true_node = node->cl_head; } else if (cb->flavor == CIL_CONDFALSE) { false_node = node->cl_head; } } if (node->cl_head != NULL && node->cl_head->next != NULL && node->cl_head->next->flavor == CIL_CONDBLOCK) { cb = node->cl_head->next->data; if (cb->flavor == CIL_CONDTRUE) { true_node = node->cl_head->next; } else if (cb->flavor == CIL_CONDFALSE) { false_node = node->cl_head->next; } } fprintf(file_arr[file_index], "{\n"); if (true_node != NULL) { rc = cil_tree_walk(true_node, __cil_booleanif_node_helper, __cil_booleanif_last_child_helper, NULL, &extra_args); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to write booleanif content to file, rc: %d\n", rc); return rc; } } fprintf(file_arr[file_index], "}\n"); if (false_node != NULL) { fprintf(file_arr[file_index], "else {\n"); rc = cil_tree_walk(false_node, __cil_booleanif_node_helper, __cil_booleanif_last_child_helper, NULL, &extra_args); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to write booleanif false content to file, rc: %d\n", rc); return rc; } fprintf(file_arr[file_index], "}\n"); } return SEPOL_OK; } int cil_name_to_policy(FILE **file_arr, struct cil_tree_node *current) { uint32_t flavor = current->flavor; int rc = SEPOL_ERR; switch(flavor) { case CIL_TYPEATTRIBUTE: fprintf(file_arr[TYPEATTRTYPES], "attribute %s;\n", ((struct cil_symtab_datum*)current->data)->name); break; case CIL_TYPE: fprintf(file_arr[TYPEATTRTYPES], "type %s;\n", ((struct cil_symtab_datum*)current->data)->name); break; case CIL_TYPEALIAS: { struct cil_alias *alias = current->data; fprintf(file_arr[ALIASES], "typealias %s alias %s;\n", ((struct cil_symtab_datum*)alias->actual)->name, ((struct cil_symtab_datum*)current->data)->name); break; } case CIL_TYPEBOUNDS: { struct cil_bounds *bnds = current->data; fprintf(file_arr[ALLOWS], "typebounds %s %s;\n", bnds->parent_str, bnds->child_str); break; } case CIL_TYPEPERMISSIVE: { struct cil_typepermissive *typeperm = (struct cil_typepermissive*)current->data; fprintf(file_arr[TYPEATTRTYPES], "permissive %s;\n", ((struct cil_symtab_datum*)typeperm->type)->name); break; } case CIL_ROLE: fprintf(file_arr[TYPEATTRTYPES], "role %s;\n", ((struct cil_symtab_datum*)current->data)->name); break; case CIL_BOOL: { const char *boolean = ((struct cil_bool*)current->data)->value ? "true" : "false"; fprintf(file_arr[TYPEATTRTYPES], "bool %s %s;\n", ((struct cil_symtab_datum*)current->data)->name, boolean); break; } case CIL_COMMON: fprintf(file_arr[COMMONS], "common %s", ((struct cil_symtab_datum*)current->data)->name); if (current->cl_head != NULL) { current = current->cl_head; fprintf(file_arr[COMMONS], " {"); } else { cil_log(CIL_INFO, "No permissions given\n"); return SEPOL_ERR; } while (current != NULL) { if (current->flavor == CIL_PERM) { fprintf(file_arr[COMMONS], "%s ", ((struct cil_symtab_datum*)current->data)->name); } else { cil_log(CIL_INFO, "Improper data type found in common permissions: %d\n", current->flavor); return SEPOL_ERR; } current = current->next; } fprintf(file_arr[COMMONS], "}\n"); return SEPOL_DONE; case CIL_AVRULE: { struct cil_avrule *avrule = (struct cil_avrule*)current->data; rc = cil_avrule_to_policy(file_arr, ALLOWS, avrule); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to write avrule to policy\n"); return rc; } break; } case CIL_TYPE_RULE: { struct cil_type_rule *rule = (struct cil_type_rule*)current->data; rc = cil_typerule_to_policy(file_arr, ALLOWS, rule); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to write type rule to policy\n"); return rc; } break; } case CIL_NAMETYPETRANSITION: { struct cil_nametypetransition *nametypetrans = (struct cil_nametypetransition*)current->data; rc = cil_nametypetransition_to_policy(file_arr, ALLOWS, nametypetrans); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to write nametypetransition to policy\n"); return rc; } } case CIL_ROLETRANSITION: { struct cil_roletransition *roletrans = (struct cil_roletransition*)current->data; char *src_str = ((struct cil_symtab_datum*)roletrans->src)->name; char *tgt_str = ((struct cil_symtab_datum*)roletrans->tgt)->name; char *obj_str = ((struct cil_symtab_datum*)roletrans->obj)->name; char *result_str = ((struct cil_symtab_datum*)roletrans->result)->name; fprintf(file_arr[ALLOWS], "role_transition %s %s:%s %s;\n", src_str, tgt_str, obj_str, result_str); break; } case CIL_ROLEALLOW: { struct cil_roleallow *roleallow = (struct cil_roleallow*)current->data; char *src_str = ((struct cil_symtab_datum*)roleallow->src)->name; char *tgt_str = ((struct cil_symtab_datum*)roleallow->tgt)->name; fprintf(file_arr[ALLOWS], "roleallow %s %s;\n", src_str, tgt_str); break; } case CIL_ROLETYPE: { struct cil_roletype *roletype = (struct cil_roletype*)current->data; char *role_str = ((struct cil_symtab_datum*)roletype->role)->name; char *type_str = ((struct cil_symtab_datum*)roletype->type)->name; fprintf(file_arr[ALIASES], "role %s types %s\n", role_str, type_str); break; } case CIL_LEVEL: fprintf(file_arr[LEVELS], "level "); cil_level_to_policy(file_arr, LEVELS, (struct cil_level*)current->data); fprintf(file_arr[LEVELS], ";\n"); break; case CIL_CONSTRAIN: cil_constrain_to_policy(file_arr, CONSTRAINS, (struct cil_constrain*)current->data, flavor); break; case CIL_MLSCONSTRAIN: cil_constrain_to_policy(file_arr, CONSTRAINS, (struct cil_constrain*)current->data, flavor); break; case CIL_VALIDATETRANS: { struct cil_validatetrans *vt = current->data; fprintf(file_arr[CONSTRAINS], "validatetrans"); fprintf(file_arr[CONSTRAINS], " %s ", ((struct cil_class*)vt->class)->datum.name); cil_expr_to_policy(file_arr, CONSTRAINS, vt->datum_expr); fprintf(file_arr[CONSTRAINS], ";\n"); break; } case CIL_MLSVALIDATETRANS: { struct cil_validatetrans *vt = current->data; fprintf(file_arr[CONSTRAINS], "mlsvalidatetrans"); fprintf(file_arr[CONSTRAINS], " %s " , ((struct cil_class*)vt->class)->datum.name); cil_expr_to_policy(file_arr, CONSTRAINS, vt->datum_expr); fprintf(file_arr[CONSTRAINS], ";\n"); break; } case CIL_SID: fprintf(file_arr[ISIDS], "sid %s\n", ((struct cil_symtab_datum*)current->data)->name); break; case CIL_SIDCONTEXT: { struct cil_sidcontext *sidcon = (struct cil_sidcontext*)current->data; fprintf(file_arr[SIDS], "sid %s ", sidcon->sid_str); cil_context_to_policy(file_arr, SIDS, sidcon->context); fprintf(file_arr[SIDS], "\n"); break; } case CIL_POLICYCAP: fprintf(file_arr[TYPEATTRTYPES], "policycap %s;\n", ((struct cil_symtab_datum*)current->data)->name); break; default: break; } return SEPOL_OK; } int __cil_gen_policy_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) { int rc = SEPOL_ERR; struct cil_args_genpolicy *args = NULL; struct cil_list *users = NULL; struct cil_list *sens = NULL; struct cil_list *cats = NULL; FILE **file_arr = NULL; if (extra_args == NULL) { return SEPOL_ERR; } *finished = CIL_TREE_SKIP_NOTHING; args = extra_args; users = args->users; sens = args->sens; cats = args->cats; file_arr = args->file_arr; if (node->cl_head != NULL) { if (node->flavor == CIL_MACRO) { *finished = CIL_TREE_SKIP_HEAD; return SEPOL_OK; } if (node->flavor == CIL_BOOLEANIF) { rc = cil_booleanif_to_policy(file_arr, CONDS, node); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to write booleanif contents to file\n"); return rc; } *finished = CIL_TREE_SKIP_HEAD; return SEPOL_OK; } if (node->flavor == CIL_OPTIONAL) { if (((struct cil_symtab_datum *)node->data)->state != CIL_STATE_ENABLED) { *finished = CIL_TREE_SKIP_HEAD; } return SEPOL_OK; } if (node->flavor == CIL_BLOCK && ((struct cil_block*)node->data)->is_abstract == CIL_TRUE) { *finished = CIL_TREE_SKIP_HEAD; return SEPOL_OK; } if (node->flavor != CIL_ROOT) { rc = cil_name_to_policy(file_arr, node); if (rc != SEPOL_OK && rc != SEPOL_DONE) { cil_log(CIL_ERR, "Error converting node to policy %d\n", node->flavor); return SEPOL_ERR; } } } else { switch (node->flavor) { case CIL_USER: cil_multimap_insert(users, node->data, NULL, CIL_USERROLE, CIL_NONE); break; case CIL_USERROLE: { struct cil_userrole *userrole = node->data; cil_multimap_insert(users, &userrole->user->datum, (struct cil_symtab_datum *)userrole->role, CIL_USERROLE, CIL_ROLE); } break; case CIL_CATALIAS: { struct cil_alias *alias = node->data; struct cil_symtab_datum *datum = alias->actual; cil_multimap_insert(cats, datum, node->data, CIL_CAT, CIL_CATALIAS); } break; case CIL_SENSALIAS: { struct cil_alias *alias = node->data; struct cil_symtab_datum *datum = alias->actual; cil_multimap_insert(sens, datum, node->data, CIL_SENS, CIL_SENSALIAS); } break; default: rc = cil_name_to_policy(file_arr, node); if (rc != SEPOL_OK && rc != SEPOL_DONE) { cil_log(CIL_ERR, "Error converting node to policy %d\n", rc); return SEPOL_ERR; } break; } } return SEPOL_OK; } int cil_gen_policy(struct cil_db *db) { struct cil_tree_node *curr = db->ast->root; struct cil_list_item *item; int rc = SEPOL_ERR; FILE *policy_file; FILE **file_arr = cil_malloc(sizeof(FILE*) * NUM_POLICY_FILES); char *file_path_arr[NUM_POLICY_FILES]; char temp[32]; struct cil_list *users = NULL; struct cil_list *cats = NULL; struct cil_list *sens = NULL; struct cil_args_genpolicy extra_args; cil_list_init(&users, CIL_LIST_ITEM); cil_list_init(&cats, CIL_LIST_ITEM); cil_list_init(&sens, CIL_LIST_ITEM); strcpy(temp, "/tmp/cil_classdecl-XXXXXX"); file_arr[CLASS_DECL] = fdopen(mkstemp(temp), "w+"); file_path_arr[CLASS_DECL] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_isids-XXXXXX"); file_arr[ISIDS] = fdopen(mkstemp(temp), "w+"); file_path_arr[ISIDS] = cil_strpool_add(temp); strcpy(temp,"/tmp/cil_common-XXXXXX"); file_arr[COMMONS] = fdopen(mkstemp(temp), "w+"); file_path_arr[COMMONS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_class-XXXXXX"); file_arr[CLASSES] = fdopen(mkstemp(temp), "w+"); file_path_arr[CLASSES] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_interf-XXXXXX"); file_arr[INTERFACES] = fdopen(mkstemp(temp), "w+"); file_path_arr[INTERFACES] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_sens-XXXXXX"); file_arr[SENS] = fdopen(mkstemp(temp), "w+"); file_path_arr[SENS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_cats-XXXXXX"); file_arr[CATS] = fdopen(mkstemp(temp), "w+"); file_path_arr[CATS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_levels-XXXXXX"); file_arr[LEVELS] = fdopen(mkstemp(temp), "w+"); file_path_arr[LEVELS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_mlscon-XXXXXX"); file_arr[CONSTRAINS] = fdopen(mkstemp(temp), "w+"); file_path_arr[CONSTRAINS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_attrtypes-XXXXXX"); file_arr[TYPEATTRTYPES] = fdopen(mkstemp(temp), "w+"); file_path_arr[TYPEATTRTYPES] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_aliases-XXXXXX"); file_arr[ALIASES] = fdopen(mkstemp(temp), "w+"); file_path_arr[ALIASES] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_allows-XXXXXX"); file_arr[ALLOWS] = fdopen(mkstemp(temp), "w+"); file_path_arr[ALLOWS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_conds-XXXXXX"); file_arr[CONDS] = fdopen(mkstemp(temp), "w+"); file_path_arr[CONDS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_userroles-XXXXXX"); file_arr[USERROLES] = fdopen(mkstemp(temp), "w+"); file_path_arr[USERROLES] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_sids-XXXXXX"); file_arr[SIDS] = fdopen(mkstemp(temp), "w+"); file_path_arr[SIDS] = cil_strpool_add(temp); strcpy(temp, "/tmp/cil_netifcons-XXXXXX"); file_arr[NETIFCONS] = fdopen(mkstemp(temp), "w+"); file_path_arr[NETIFCONS] = cil_strpool_add(temp); policy_file = fopen("policy.conf", "w+"); cil_list_for_each(item, db->sidorder) { fprintf(file_arr[ISIDS], "sid %s ", ((struct cil_sid*)item->data)->datum.name); } cil_list_for_each(item, db->classorder) { struct cil_class *class = item->data; struct cil_tree_node *node = class->datum.nodes->head->data; fprintf(file_arr[CLASS_DECL], "class %s\n", class->datum.name); fprintf(file_arr[CLASSES], "class %s ", class->datum.name); if (class->common != NULL) { fprintf(file_arr[CLASSES], "inherits %s ", class->common->datum.name); } if (node->cl_head != NULL) { struct cil_tree_node *curr_perm = node->cl_head; fprintf(file_arr[CLASSES], "{ "); while (curr_perm != NULL) { fprintf(file_arr[CLASSES], "%s ", ((struct cil_symtab_datum*)curr_perm->data)->name); curr_perm = curr_perm->next; } fprintf(file_arr[CLASSES], "}"); } fprintf(file_arr[CLASSES], "\n"); } if (db->catorder->head != NULL) { cil_list_for_each(item, db->catorder) { cil_multimap_insert(cats, item->data, NULL, CIL_CAT, 0); } } if (db->sensitivityorder->head != NULL) { fprintf(file_arr[SENS], "sensitivityorder { "); cil_list_for_each(item, db->sensitivityorder) { fprintf(file_arr[SENS], "%s ", ((struct cil_sens*)item->data)->datum.name); } fprintf(file_arr[SENS], "};\n"); } extra_args.users = users; extra_args.sens = sens; extra_args.cats = cats; extra_args.file_arr= file_arr; rc = cil_tree_walk(curr, __cil_gen_policy_node_helper, NULL, NULL, &extra_args); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error walking tree\n"); return rc; } rc = cil_netifcon_to_policy(file_arr, db->netifcon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_genfscon_to_policy(file_arr, db->genfscon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_portcon_to_policy(file_arr, db->portcon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_nodecon_to_policy(file_arr, db->nodecon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_fsuse_to_policy(file_arr, db->fsuse); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_pirqcon_to_policy(file_arr, db->pirqcon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_iomemcon_to_policy(file_arr, db->iomemcon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_ioportcon_to_policy(file_arr, db->ioportcon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_pcidevicecon_to_policy(file_arr, db->pcidevicecon); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } rc = cil_userrole_to_policy(file_arr, users); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return SEPOL_ERR; } rc = cil_sens_to_policy(file_arr, sens); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return SEPOL_ERR; } rc = cil_cat_to_policy(file_arr, cats); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return SEPOL_ERR; } rc = cil_combine_policy(file_arr, policy_file); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Error creating policy.conf\n"); return SEPOL_ERR; } // Remove temp files int i; for (i=0; i #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" 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 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; } void cil_post_fc_fill_data(struct fc_data *fc, char *path) { int 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++; 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); a_path[0] = '\0'; char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1); 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; } free(a_path); free(b_path); free(a_data); free(b_data); 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; } } 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_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)); } } 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; } 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; } 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; } 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; } 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_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_OPTIONAL: { struct cil_optional *opt = node->data; if (opt->datum.state != CIL_STATE_ENABLED) { *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 (type->datum.nodes->head->data == node) { // multiple AST nodes can point to the same cil_type data (like if // copied from a macro). This check ensures we only count the // duplicates once type->value = db->num_types; db->num_types++; } break; } case CIL_ROLE: { struct cil_role *role = node->data; if (role->datum.nodes->head->data == node) { // multiple AST nodes can point to the same cil_role data (like if // copied from a macro). This check ensures we only count the // duplicates once role->value = db->num_roles; db->num_roles++; } 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_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_FSUSE: db->fsuse->count++; break; default: break; } return SEPOL_OK; } static int __cil_post_db_array_helper(struct cil_tree_node *node, __attribute__((unused)) 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_OPTIONAL: { struct cil_optional *opt = node->data; if (opt->datum.state != CIL_STATE_ENABLED) { *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_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_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_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; } 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"); 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 (ebitmap_set_bit(bitmap, type->value, 1)) { cil_log(CIL_ERR, "Failed to set type bit\n"); ebitmap_destroy(bitmap); goto exit; } } else { struct cil_type *type = (struct cil_type *)datum; if (ebitmap_set_bit(bitmap, type->value, 1)) { cil_log(CIL_ERR, "Failed to set type bit\n"); 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"); 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 (ebitmap_set_bit(bitmap, role->value, 1)) { cil_log(CIL_ERR, "Failed to set role bit\n"); 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 (ebitmap_set_bit(bitmap, value, 1)) { cil_log(CIL_INFO, "Failed to set perm bit\n"); 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"); 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 (ebitmap_get_bit(&bitmap, cat->value)) { cil_list_append(new, CIL_DATUM, cat); } } ebitmap_destroy(&bitmap); cil_list_destroy(&cats->datum_expr, CIL_FALSE); if (new->head != NULL) { cats->datum_expr = new; } else { /* empty list */ cil_list_destroy(&new, CIL_FALSE); cats->datum_expr = NULL; } 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 (ebitmap_set_bit(bitmap, cat->value, 1)) { cil_log(CIL_ERR, "Failed to set cat bit\n"); 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 (ebitmap_set_bit(bitmap, cat->value, 1)) { cil_log(CIL_ERR, "Failed to set cat bit\n"); ebitmap_destroy(bitmap); goto exit; } } else { struct cil_cat *cat = (struct cil_cat *)datum; if (ebitmap_set_bit(bitmap, cat->value, 1)) { cil_log(CIL_ERR, "Failed to set cat bit\n"); ebitmap_destroy(bitmap); goto exit; } } return SEPOL_OK; exit: return rc; } static int __cil_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; } for (i = c1->value; i <= c2->value; i++) { if (ebitmap_set_bit(bitmap, i, 1)) { cil_log(CIL_ERR, "Failed to set cat bit\n"); 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_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) { ebitmap_destroy(bitmap); } } 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)curr->data; if (op == CIL_ALL) { ebitmap_init(&b1); /* all zeros */ rc = ebitmap_not(&tmp, &b1, max); ebitmap_destroy(&b1); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to expand 'all' operator\n"); ebitmap_destroy(&tmp); goto exit; } } else if (op == CIL_RANGE) { if (flavor != CIL_CAT) { cil_log(CIL_INFO, "Range operation only supported for categories\n"); rc = SEPOL_ERR; goto exit; } ebitmap_init(&tmp); rc = __cil_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"); ebitmap_destroy(&tmp); 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); ebitmap_destroy(&b1); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to NOT bitmap\n"); 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"); goto exit; } if (op == CIL_OR) { rc = ebitmap_or(&tmp, &b1, &b2); } else if (op == CIL_AND) { rc = ebitmap_and(&tmp, &b1, &b2); } else if (op == CIL_XOR) { rc = ebitmap_xor(&tmp, &b1, &b2); } else { rc = SEPOL_ERR; } ebitmap_destroy(&b1); ebitmap_destroy(&b2); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to apply operator to bitmaps\n"); 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"); ebitmap_destroy(&tmp); goto exit; } b1 = tmp; rc = ebitmap_or(&tmp, &b1, &b2); ebitmap_destroy(&b1); ebitmap_destroy(&b2); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failed to OR operands in list\n"); ebitmap_destroy(&tmp); goto exit; } } } ebitmap_union(out, &tmp); 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"); ebitmap_destroy(&bitmap); goto exit; } ebitmap_union(out, &bitmap); ebitmap_destroy(&bitmap); } return SEPOL_OK; exit: return SEPOL_ERR; } static int __cil_post_db_attr_helper(struct cil_tree_node *node, __attribute__((unused)) 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_OPTIONAL: { struct cil_optional *opt = node->data; if (opt->datum.state != CIL_STATE_ENABLED) { *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; } 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; } 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 (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 (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, __attribute__((unused)) 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_OPTIONAL: { struct cil_optional *opt = node->data; if (opt->datum.state != CIL_STATE_ENABLED) { *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_bit(attr->roles, rnode, i) { struct cil_role *role = NULL; if (!ebitmap_get_bit(attr->roles, i)) { continue; } 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 __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_OPTIONAL: { struct cil_optional *opt = node->data; if (opt->datum.state != CIL_STATE_ENABLED) { *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_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_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 (!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) { 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); } 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; 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_OPTIONAL: { struct cil_optional *opt = node->data; if (opt->datum.state != CIL_STATE_ENABLED) { *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->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_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 databse 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_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_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; } qsort(db->netifcon->array, db->netifcon->count, sizeof(db->netifcon->array), cil_post_netifcon_compare); qsort(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare); qsort(db->portcon->array, db->portcon->count, sizeof(db->portcon->array), cil_post_portcon_compare); qsort(db->nodecon->array, db->nodecon->count, sizeof(db->nodecon->array), cil_post_nodecon_compare); qsort(db->fsuse->array, db->fsuse->count, sizeof(db->fsuse->array), cil_post_fsuse_compare); qsort(db->filecon->array, db->filecon->count, sizeof(db->filecon->array), cil_post_filecon_compare); qsort(db->pirqcon->array, db->pirqcon->count, sizeof(db->pirqcon->array), cil_post_pirqcon_compare); qsort(db->iomemcon->array, db->iomemcon->count, sizeof(db->iomemcon->array), cil_post_iomemcon_compare); qsort(db->ioportcon->array, db->ioportcon->count, sizeof(db->ioportcon->array), cil_post_ioportcon_compare); qsort(db->pcidevicecon->array, db->pcidevicecon->count, sizeof(db->pcidevicecon->array), cil_post_pcidevicecon_compare); 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; } int cil_post_process(struct cil_db *db) { int rc = SEPOL_ERR; rc = cil_verify_no_classperms_loop(db); if (rc != SEPOL_OK) { 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; } libsepol-2.4/cil/src/cil_post.h000066400000000000000000000042671246370572200165340ustar00rootroot00000000000000/* * 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_ struct fc_data { int meta; int stem_len; int str_len; }; void cil_post_fc_fill_data(struct fc_data *fc, char *path); int cil_post_filecon_compare(const void *a, const void *b); int cil_post_portcon_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 libsepol-2.4/cil/src/cil_reset_ast.c000066400000000000000000000276201246370572200175310ustar00rootroot00000000000000 #include "cil_internal.h" #include "cil_log.h" #include "cil_list.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) { struct cil_class *common = class->common; cil_symtab_map(&common->perms, __class_reset_perm_values, &common->num_perms); /* during a re-resolve, we need to reset the common, so a classcommon * statement isn't seen as a duplicate */ class->num_perms -= common->num_perms; 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_reset_classperms_list(perm->classperms); } static inline void cil_reset_classperms(struct cil_classperms *cp) { if (cp == NULL) { return; } cil_list_destroy(&cp->perms, CIL_FALSE); } 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, but not SET */ cil_reset_classperms(curr->data); } } } static void cil_reset_classpermission(struct cil_classpermission *cp) { cil_reset_classperms_list(cp->classperms); } 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; cil_list_destroy(&user->roles, CIL_FALSE); } static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser) { if (selinuxuser->range_str == NULL) { cil_reset_levelrange(selinuxuser->range); } } 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; } static void cil_reset_typeattributeset(struct cil_typeattributeset *tas) { cil_list_destroy(&tas->datum_expr, CIL_FALSE); } static void cil_reset_avrule(struct cil_avrule *rule) { cil_reset_classperms_list(rule->classperms); } static void cil_reset_rangetransition(struct cil_rangetransition *rangetrans) { if (rangetrans->range_str == NULL) { cil_reset_levelrange(rangetrans->range); } } 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) { 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); } if (levelrange->high_str == NULL) { cil_reset_level(levelrange->high); } } static inline void cil_reset_userlevel(struct cil_userlevel *userlevel) { if (userlevel->level_str == NULL) { cil_reset_level(userlevel->level); } } static inline void cil_reset_userrange(struct cil_userrange *userrange) { if (userrange->range_str == NULL) { cil_reset_levelrange(userrange->range); } } static inline void cil_reset_context(struct cil_context *context) { if (context->range_str == NULL) { cil_reset_levelrange(context->range); } } static void cil_reset_sidcontext(struct cil_sidcontext *sidcontext) { if (sidcontext->context_str == NULL) { cil_reset_context(sidcontext->context); } } static void cil_reset_filecon(struct cil_filecon *filecon) { if (filecon->context_str == NULL && filecon->context != NULL) { cil_reset_context(filecon->context); } } static void cil_reset_portcon(struct cil_portcon *portcon) { if (portcon->context_str == NULL) { cil_reset_context(portcon->context); } } static void cil_reset_nodecon(struct cil_nodecon *nodecon) { if (nodecon->context_str == NULL) { cil_reset_context(nodecon->context); } } static void cil_reset_genfscon(struct cil_genfscon *genfscon) { if (genfscon->context_str == NULL) { cil_reset_context(genfscon->context); } } static void cil_reset_netifcon(struct cil_netifcon *netifcon) { if (netifcon->if_context_str == NULL) { cil_reset_context(netifcon->if_context); } if (netifcon->packet_context_str == NULL) { cil_reset_context(netifcon->packet_context); } } static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon) { if (pirqcon->context_str == NULL) { cil_reset_context(pirqcon->context); } } static void cil_reset_iomemcon(struct cil_iomemcon *iomemcon) { if (iomemcon->context_str == NULL) { cil_reset_context(iomemcon->context); } } static void cil_reset_ioportcon(struct cil_ioportcon *ioportcon) { if (ioportcon->context_str == NULL) { cil_reset_context(ioportcon->context); } } static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon) { if (pcidevicecon->context_str == NULL) { cil_reset_context(pcidevicecon->context); } } static void cil_reset_fsuse(struct cil_fsuse *fsuse) { if (fsuse->context_str == NULL) { cil_reset_context(fsuse->context); } } 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); } 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_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_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_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_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; } libsepol-2.4/cil/src/cil_reset_ast.h000066400000000000000000000002331246370572200175250ustar00rootroot00000000000000#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_ */ libsepol-2.4/cil/src/cil_resolve_ast.c000066400000000000000000003017541246370572200200710ustar00rootroot00000000000000/* * 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" 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 *boolif; struct cil_tree_node *macro; struct cil_list *sidorder_lists; struct cil_list *classorder_lists; struct cil_list *catorder_lists; struct cil_list *sensitivityorder_lists; struct cil_list *in_list; }; 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; 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; } 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) { struct cil_list_item *item; cil_list_for_each(item, macro->params) { if (((struct cil_param*)item->data)->str == key) { return NULL; } } } 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) { 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); 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) { 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: 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; 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); if (rc != SEPOL_OK) { goto exit; } return SEPOL_OK; exit: return rc; } 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; } int cil_type_used(struct cil_symtab_datum *datum) { struct cil_typeattribute *attr = NULL; if (FLAVOR(datum) == CIL_TYPEATTRIBUTE) { attr = (struct cil_typeattribute*)datum; attr->used = CIL_TRUE; } return 0; } 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; 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->rule_kind != CIL_AVRULE_NEVERALLOW) { cil_type_used(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; if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { cil_type_used(tgt_datum); } } rc = cil_resolve_classperms_list(current, rule->classperms, 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_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; cil_type_used(src_datum); 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; cil_type_used(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 = result_datum->nodes->head->data; 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 = attr_datum->nodes->head->data; 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; } rc = cil_verify_no_self_reference(attr_datum, attrtypes->datum_expr); 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; } int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enum cil_flavor 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(current, aliasactual->alias_str, sym_index, extra_args, &alias_datum); if (rc != SEPOL_OK) { goto exit; } rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, extra_args, &actual_datum); if (rc != SEPOL_OK) { goto exit; } alias = (struct cil_alias *)alias_datum; if (alias->actual != NULL) { cil_log(CIL_ERR, "Alias cannot bind more than one value\n"); rc = SEPOL_ERR; goto exit; } alias->actual = actual_datum; return SEPOL_OK; exit: return rc; } 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_log(CIL_ERR, "Alias declared but not used at line %d of %s\n",current->line, current->path); return SEPOL_ERR; } a1_node = a1->datum.nodes->head->data; while (flavor != a1_node->flavor) { 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 = type_datum->nodes->head->data; 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; cil_type_used(src_datum); 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; cil_type_used(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 = result_datum->nodes->head->data; 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; cil_type_used(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; cil_type_used(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; } 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; } 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; 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; if (userrole->user->roles == NULL) { cil_list_init(&userrole->user->roles, CIL_LIST_ITEM); } cil_list_append(userrole->user->roles, CIL_ROLE, userrole->role); 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; 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 = (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; 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 = (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; 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; } 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; 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; } 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) { cil_log(CIL_ERR, "Unable to resolve name: %s\n", selinuxuser->range_str); 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; cil_type_used(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; cil_type_used(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 = result_datum->nodes->head->data; if (node->flavor != CIL_ROLE) { rc = SEPOL_ERR; printf("%i\n", node->flavor); 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 = attr_datum->nodes->head->data; 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; } rc = cil_verify_no_self_reference(attr_datum, attrroles->datum_expr); 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; }; 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; } void __cil_ordered_list_destroy(struct cil_ordered_list **ordered) { cil_list_destroy(&(*ordered)->list, CIL_FALSE); (*ordered)->node = NULL; free(*ordered); *ordered = NULL; } void __cil_ordered_lists_destroy(struct cil_list **ordered_lists) { struct cil_list_item *item = NULL; if (*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; } void __cil_ordered_lists_reset(struct cil_list **ordered_lists) { __cil_ordered_lists_destroy(ordered_lists); cil_list_init(ordered_lists, CIL_LIST_ITEM); } 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); } 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; } 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; } 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; } struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_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_log(CIL_ERR, "Unable to merge ordered list at line %d of %s\n",ordered_list->node->line, ordered_list->node->path); } } goto exit; } } __cil_ordered_lists_destroy(ordered_lists); return composite; exit: 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_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 *ordered = NULL; int rc = SEPOL_ERR; cil_list_init(&new, CIL_CLASSORDER); cil_list_for_each(curr, classorder->class_list_str) { 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); goto exit; } cil_list_append(new, CIL_CLASS, datum); } __cil_ordered_list_init(&ordered); ordered->list = new; ordered->node = current; cil_list_append(classorder_list, CIL_CLASSORDER, ordered); return SEPOL_OK; exit: 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; } 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: return rc; } 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 = cat_datum->nodes->head->data; 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: 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 sensitivty %s in sensitivityorder\n", (char *)curr->data); 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: return rc; } 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) { cil_log(CIL_ERR,"Unable to resolve categories\n"); goto exit; } return SEPOL_OK; exit: return rc; } int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args) { int rc = SEPOL_ERR; rc = cil_resolve_cats(current, catset->cats, extra_args); if (rc != SEPOL_OK) { goto exit; } rc = cil_verify_no_self_reference((struct cil_symtab_datum *)catset, catset->cats->datum_expr); if (rc != SEPOL_OK) { cil_list_destroy(&catset->cats->datum_expr, CIL_FALSE); goto exit; } exit: return rc; } 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; 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 *type_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) { cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->user_str); 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) { cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->role_str); 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) { cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->type_str); goto exit; } type_node = type_datum->nodes->head->data; if (type_node->flavor != CIL_TYPE && 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) { cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->range_str); 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_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_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; } 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; } int cil_resolve_blockinherit(struct cil_tree_node *current, void *extra_args) { struct cil_blockinherit *inherit = 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, inherit->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); if (rc != SEPOL_OK) { goto exit; } block_node = block_datum->nodes->head->data; rc = cil_copy_ast(db, block_node, current); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to copy block, rc: %d\n", rc); goto exit; } return SEPOL_OK; exit: return rc; } 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; 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 = block_datum->nodes->head->data; if (block_node->flavor != CIL_BLOCK) { cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc); goto exit; } ((struct cil_block*)block_datum)->is_abstract = CIL_TRUE; 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 = block_datum->nodes->head->data; rc = cil_copy_ast(db, current, block_node); if (rc != SEPOL_OK) { printf("Failed to copy in, rc: %d\n", rc); goto exit; } cil_tree_children_destroy(current); current->cl_head = NULL; current->cl_tail = NULL; return SEPOL_OK; exit: return rc; } int cil_resolve_in_list(void *extra_args) { struct cil_args_resolve *args = extra_args; struct cil_list *ins = args->in_list; 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, ins) { 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_log(CIL_ERR, "Failed to resolve in-statement on line %d of %s\n", last_failed_node->line, last_failed_node->path); rc = SEPOL_ERR; goto exit; } } while (unresolved > 0); rc = SEPOL_OK; exit: return rc; } int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil_flavor 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; } rc = cil_resolve_name(current, bounds->child_str, index, extra_args, &child_datum); if (rc != SEPOL_OK) { goto exit; } switch (flavor) { case CIL_USER: { struct cil_user *user = (struct cil_user *)child_datum; if (user->bounds != NULL) { struct cil_tree_node *node = user->bounds->datum.nodes->head->data; cil_log(CIL_ERR, "User %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path); 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) { struct cil_tree_node *node = role->bounds->datum.nodes->head->data; cil_log(CIL_ERR, "Role %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path); 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; struct cil_tree_node *node = NULL; if (type->bounds != NULL) { node = ((struct cil_symtab_datum *)type->bounds)->nodes->head->data; cil_log(CIL_ERR, "Type %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path); cil_log(CIL_ERR, "Now being bound to parent %s at line %u of %s\n", bounds->parent_str, current->line, current->path); rc = SEPOL_ERR; goto exit; } node = parent_datum->nodes->head->data; if (node->flavor == CIL_TYPEATTRIBUTE) { cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str); rc = SEPOL_ERR; goto exit; } node = child_datum->nodes->head->data; if (node->flavor == CIL_TYPEATTRIBUTE) { cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str); rc = SEPOL_ERR; goto exit; } type->bounds = (struct cil_type *)parent_datum; break; } default: break; } return SEPOL_OK; exit: cil_log(CIL_ERR, "Bad bounds statement at line %u of %s\n", current->line, current->path); return rc; } 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) { cil_log(CIL_ERR, "Failed to resolve class %s in %s\n", (char *)curr->data, cil_node_to_string(current)); goto exit; } cil_list_append(def->class_datums, CIL_CLASS, datum); } return SEPOL_OK; exit: return rc; } 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) { cil_log(CIL_ERR, "Failed to resolve class %s in defaultrange\n", (char *)curr->data); goto exit; } cil_list_append(def->class_datums, CIL_CLASS, datum); } return SEPOL_OK; exit: return rc; } int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) { struct cil_call *new_call = current->data; struct cil_args_resolve *args = extra_args; struct cil_db *db = NULL; struct cil_tree_node *macro_node = NULL; struct cil_symtab_datum *macro_datum = NULL; int rc = SEPOL_ERR; if (args != NULL) { db = args->db; } rc = cil_resolve_name(current, new_call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum); if (rc != SEPOL_OK) { goto exit; } macro_node = macro_datum->nodes->head->data; if (macro_node->flavor != CIL_MACRO) { printf("Failed to resolve macro %s\n", new_call->macro_str); rc = SEPOL_ERR; goto exit; } new_call->macro = (struct cil_macro*)macro_datum; if (new_call->macro->params != NULL ) { struct cil_list_item *item; struct cil_args *new_arg = NULL; struct cil_tree_node *pc = NULL; if (new_call->args_tree == NULL) { cil_log(CIL_ERR, "Missing arguments (%s, line: %d)\n", current->path, current->line); rc = SEPOL_ERR; goto exit; } pc = new_call->args_tree->root->cl_head; cil_list_init(&new_call->args, CIL_LIST_ITEM); cil_list_for_each(item, new_call->macro->params) { enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor; if (pc == NULL) { cil_log(CIL_ERR, "Missing arguments (%s, line: %d)\n", current->path, current->line); rc = SEPOL_ERR; goto exit; } if (item->flavor != CIL_PARAM) { rc = SEPOL_ERR; goto exit; } cil_args_init(&new_arg); switch (flavor) { case CIL_NAME: { struct cil_name *name; name = __cil_insert_name(args->db, pc->data, current); if (name != NULL) { new_arg->arg = (struct cil_symtab_datum *)name; } else { new_arg->arg_str = pc->data; } } break; case CIL_TYPE: new_arg->arg_str = pc->data; break; case CIL_ROLE: new_arg->arg_str = pc->data; break; case CIL_USER: new_arg->arg_str = pc->data; break; case CIL_SENS: new_arg->arg_str = pc->data; break; case CIL_CAT: new_arg->arg_str = pc->data; break; case CIL_BOOL: new_arg->arg_str = pc->data; break; case CIL_CATSET: { if (pc->cl_head != NULL) { struct cil_catset *catset = NULL; struct cil_tree_node *cat_node = NULL; cil_catset_init(&catset); rc = cil_fill_cats(pc, &catset->cats); if (rc != SEPOL_OK) { cil_destroy_catset(catset); 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); new_arg->arg = (struct cil_symtab_datum*)catset; } else { new_arg->arg_str = pc->data; } break; } case CIL_LEVEL: { if (pc->cl_head != NULL) { struct cil_level *level = NULL; struct cil_tree_node *lvl_node = NULL; cil_level_init(&level); rc = cil_fill_level(pc->cl_head, level); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc); cil_destroy_level(level); 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); new_arg->arg = (struct cil_symtab_datum*)level; } else { new_arg->arg_str = pc->data; } break; } case CIL_LEVELRANGE: { if (pc->cl_head != NULL) { struct cil_levelrange *range = NULL; struct cil_tree_node *range_node = NULL; cil_levelrange_init(&range); rc = cil_fill_levelrange(pc->cl_head, range); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc); cil_destroy_levelrange(range); 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); new_arg->arg = (struct cil_symtab_datum*)range; } else { new_arg->arg_str = pc->data; } break; } case CIL_IPADDR: { if (pc->cl_head != NULL) { struct cil_ipaddr *ipaddr = NULL; struct cil_tree_node *addr_node = NULL; cil_ipaddr_init(&ipaddr); rc = cil_fill_ipaddr(pc->cl_head, ipaddr); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to create anonymous ip address, rc; %d\n", rc); cil_destroy_ipaddr(ipaddr); goto exit; } cil_tree_node_init(&addr_node); addr_node->flavor = CIL_IPADDR; addr_node->data = ipaddr; cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes, CIL_LIST_ITEM, addr_node); new_arg->arg = (struct cil_symtab_datum*)ipaddr; } else { new_arg->arg_str = pc->data; } break; } case CIL_CLASS: new_arg->arg_str = pc->data; break; case CIL_MAP_CLASS: new_arg->arg_str = pc->data; break; case CIL_CLASSPERMISSION: { if (pc->cl_head != NULL) { struct cil_classpermission *cp = NULL; struct cil_tree_node *cp_node = NULL; cil_classpermission_init(&cp); rc = cil_fill_classperms_list(pc, &cp->classperms); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to create anonymous classpermission\n"); cil_destroy_classpermission(cp); 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); new_arg->arg = (struct cil_symtab_datum*)cp; } else { new_arg->arg_str = pc->data; } break; } default: cil_log(CIL_ERR, "Unexpected flavor: %d\n", (((struct cil_param*)item->data)->flavor)); rc = SEPOL_ERR; goto exit; } new_arg->param_str = ((struct cil_param*)item->data)->str; new_arg->flavor = flavor; cil_list_append(new_call->args, CIL_ARGS, new_arg); pc = pc->next; } if (pc != NULL) { cil_log(CIL_ERR, "Unexpected arguments (%s, line: %d)\n", current->path, current->line); rc = SEPOL_ERR; goto exit; } } else if (new_call->args_tree != NULL) { cil_log(CIL_ERR, "Unexpected arguments (%s, line: %d)\n", current->path, current->line); rc = SEPOL_ERR; goto exit; } if (new_call->copied == 0) { new_call->copied = 1; rc = cil_copy_ast(db, macro_node, current); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc); goto exit; } } return SEPOL_OK; exit: return rc; } int cil_resolve_call2(struct cil_tree_node *current, void *extra_args) { struct cil_call *new_call = current->data; int rc = SEPOL_ERR; enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; struct cil_list_item *item; if (new_call->args == NULL) { rc = SEPOL_OK; goto exit; } cil_list_for_each(item, new_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) { rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg)); if (rc != SEPOL_OK) { goto exit; } } } 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 = SEPOL_OK; 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; 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_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) { cil_type_used(res_datum); } cil_list_append(*datum_expr, CIL_DATUM, res_datum); break; case CIL_LIST: { struct cil_list *datum_sub_expr; rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, extra_args); if (rc != SEPOL_OK) { cil_list_destroy(&datum_sub_expr, CIL_TRUE); goto exit; } cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr); break; } default: cil_list_append(*datum_expr, curr->flavor, curr->data); break; } } return SEPOL_OK; exit: 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)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_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; struct cil_list *ins = args->in_list; 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: 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 cil_list_prepend(ins, CIL_NODE, node); } break; case CIL_PASS_BLKIN: if (node->flavor == CIL_BLOCKINHERIT) { rc = cil_resolve_blockinherit(node, args); } break; case CIL_PASS_BLKABS: if (node->flavor == CIL_BLOCKABSTRACT) { rc = cil_resolve_blockabstract(node, args); } break; case CIL_PASS_MACRO: if (node->flavor == CIL_CALL && args->macro != NULL) { rc = cil_resolve_call1(node, args); } break; case CIL_PASS_CALL1: if (node->flavor == CIL_CALL) { rc = cil_resolve_call1(node, args); } break; case CIL_PASS_CALL2: if (node->flavor == CIL_CALL) { rc = cil_resolve_call2(node, args); } break; case CIL_PASS_ALIAS1: switch (node->flavor) { case CIL_TYPEALIASACTUAL: rc = cil_resolve_aliasactual(node, args, CIL_TYPE); break; case CIL_SENSALIASACTUAL: rc = cil_resolve_aliasactual(node, args, CIL_SENS); break; case CIL_CATALIASACTUAL: rc = cil_resolve_aliasactual(node, args, CIL_CAT); 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_TYPEBOUNDS: rc = cil_resolve_bounds(node, args, CIL_TYPE); 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: rc = cil_resolve_avrule(node, 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); 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); 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_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_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_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; default: break; } break; default: break; } return rc; exit: return rc; } int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) { int rc = SEPOL_ERR; struct cil_args_resolve *args = extra_args; enum cil_pass pass = args->pass; struct cil_tree_node *optstack = args->optstack; struct cil_tree_node *boolif = args->boolif; if (node == NULL) { goto exit; } if (optstack != NULL) { if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) { /* tuanbles and macros are not allowed in optionals*/ cil_log(CIL_ERR, "%s statement is not allowed in optionals (%s:%d)\n", cil_node_to_string(node), node->path, node->line); rc = SEPOL_ERR; goto exit; } } if (boolif != NULL) { if (!(node->flavor == CIL_CONDBLOCK || node->flavor == CIL_AVRULE || node->flavor == CIL_TYPE_RULE || node->flavor == CIL_CALL || node->flavor == CIL_TUNABLEIF || node->flavor == CIL_NAMETYPETRANSITION)) { if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { cil_log(CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif) (%s:%d)\n", cil_node_to_string(node), node->path, node->line); } else { cil_log(CIL_ERR, "%s statement is not allowed in booleanifs (%s:%d)\n", cil_node_to_string(node), node->path, node->line); } rc = SEPOL_ERR; goto exit; } } if (node->flavor == CIL_MACRO) { if (pass != CIL_PASS_TIF && pass != CIL_PASS_MACRO) { *finished = CIL_TREE_SKIP_HEAD; rc = SEPOL_OK; goto exit; } } if (node->flavor == CIL_OPTIONAL && ((struct cil_symtab_datum *)node->data)->state == CIL_STATE_DISABLED) { /* don't try to resolve children of a disabled optional */ *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 && optstack != NULL) { struct cil_optional *opt = (struct cil_optional *)optstack->data; cil_log(CIL_WARN, "Disabling optional %s at %d of %s\n", opt->datum.name, node->parent->line, node->parent->path); /* disable an optional if something failed to resolve */ opt->datum.state = CIL_STATE_DISABLING; rc = SEPOL_OK; } else if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to resolve %s statement at %d of %s\n", cil_node_to_string(node), node->line, node->path); goto exit; } return rc; exit: return rc; } int __cil_disable_children_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) { int rc = SEPOL_ERR; struct cil_args_resolve *args = extra_args; uint32_t *changed = args->changed; if (node == NULL || finished == NULL) { goto exit; } if (node->flavor < CIL_MIN_DECLARATIVE) { /* only declarative statements need to be disabled */ rc = SEPOL_OK; goto exit; } if (node->flavor == CIL_OPTIONAL) { if (((struct cil_symtab_datum *)node->data)->state == CIL_STATE_DISABLED) { /* don't bother going into an optional that isn't enabled */ *finished = CIL_TREE_SKIP_HEAD; rc = SEPOL_OK; goto exit; } } else { /* Do we need to reset for a block? */ *changed = 1; } ((struct cil_symtab_datum *)node->data)->state = CIL_STATE_DISABLED; return SEPOL_OK; exit: return rc; } 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 *callstack = NULL; struct cil_tree_node *optstack = NULL; struct cil_tree_node *parent = NULL; if (current == NULL || extra_args == NULL) { goto exit; } callstack = args->callstack; optstack = args->optstack; parent = current->parent; if (parent->flavor == CIL_CALL || parent->flavor == CIL_OPTIONAL) { /* push this node onto a stack */ struct cil_tree_node *new; cil_tree_node_init(&new); new->data = parent->data; new->flavor = parent->flavor; if (parent->flavor == CIL_CALL) { if (callstack != NULL) { struct cil_tree_node *curr = NULL; struct cil_call *new_call = new->data; for (curr = callstack->cl_head; curr != NULL; curr = curr->cl_head) { struct cil_call *curr_call = curr->data; if (curr_call->macro == new_call->macro) { cil_log(CIL_ERR, "Recursive macro call found\n"); rc = SEPOL_ERR; goto exit; } } callstack->parent = new; new->cl_head = callstack; } args->callstack = new; } else if (parent->flavor == CIL_OPTIONAL) { if (optstack != NULL) { optstack->parent = new; new->cl_head = optstack; } args->optstack = new; } } else if (parent->flavor == CIL_BOOLEANIF) { args->boolif = parent; } else if (parent->flavor == CIL_MACRO) { args->macro = parent; } return SEPOL_OK; exit: return rc; } 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_CALL) { /* pop off the stack */ struct cil_tree_node *callstack = args->callstack; args->callstack = callstack->cl_head; if (callstack->cl_head) { callstack->cl_head->parent = NULL; } free(callstack); } else if (parent->flavor == CIL_MACRO) { args->macro = NULL; } else if (parent->flavor == CIL_OPTIONAL) { struct cil_tree_node *optstack; if (((struct cil_optional *)parent->data)->datum.state == CIL_STATE_DISABLING) { /* go into the optional, removing everything that it added */ if (args->pass >= CIL_PASS_CALL1) { rc = cil_tree_walk(parent, __cil_disable_children_helper, NULL, NULL, extra_args); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to disable declarations in optional\n"); goto exit; } } ((struct cil_optional *)parent->data)->datum.state = CIL_STATE_DISABLED; } /* pop off the stack */ optstack = args->optstack; args->optstack = optstack->cl_head; if (optstack->cl_head) { optstack->cl_head->parent = NULL; } free(optstack); } 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) { goto exit; } extra_args.db = db; extra_args.pass = pass; extra_args.changed = &changed; extra_args.callstack = NULL; extra_args.optstack = NULL; extra_args.boolif= NULL; extra_args.macro = NULL; extra_args.sidorder_lists = NULL; extra_args.classorder_lists = NULL; extra_args.catorder_lists = NULL; extra_args.sensitivityorder_lists = NULL; extra_args.in_list = NULL; 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.catorder_lists, CIL_LIST_ITEM); cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM); cil_list_init(&extra_args.in_list, CIL_IN); 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) { rc = cil_resolve_in_list(&extra_args); if (rc != SEPOL_OK) { goto exit; } cil_list_destroy(&extra_args.in_list, CIL_FALSE); } if (pass == CIL_PASS_MISC1) { db->sidorder = __cil_ordered_lists_merge_all(&extra_args.sidorder_lists); db->classorder = __cil_ordered_lists_merge_all(&extra_args.classorder_lists); db->catorder = __cil_ordered_lists_merge_all(&extra_args.catorder_lists); cil_set_cat_values(db->catorder, db); db->sensitivityorder = __cil_ordered_lists_merge_all(&extra_args.sensitivityorder_lists); 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 && (pass > CIL_PASS_CALL1)) { /* Need to re-resolve because an optional was disabled that contained * one or more declarations. We only need to reset to the call1 pass * because things done in the preceeding passes aren't allowed in * optionals, and thus can't be disabled. * Note: 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.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; } } /* reset the arguments */ changed = 0; while (extra_args.callstack != NULL) { struct cil_tree_node *curr = extra_args.callstack; struct cil_tree_node *next = curr->cl_head; free(curr); extra_args.callstack = next; } while (extra_args.optstack != NULL) { struct cil_tree_node *curr = extra_args.optstack; struct cil_tree_node *next = curr->cl_head; free(curr); extra_args.optstack = next; } } rc = __cil_verify_initsids(db->sidorder); if (rc != SEPOL_OK) { goto exit; } rc = SEPOL_OK; exit: return rc; } static int __cil_resolve_name_helper(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum) { struct cil_args_resolve *args = extra_args; struct cil_call *call = NULL; struct cil_tree_node *macro = NULL; enum cil_pass pass = CIL_PASS_INIT; int rc = SEPOL_ERR; char* name_dup = cil_strdup(name); char *tok_current = strtok(name_dup, "."); char *tok_next = strtok(NULL, "."); symtab_t *symtab = NULL; struct cil_symtab_datum *tmp_datum = NULL; enum cil_flavor flavor = CIL_NONE; if (args != NULL) { if (args->callstack != NULL) { call = args->callstack->data; } pass = args->pass; macro = args->macro; } if (ast_node->flavor == CIL_ROOT) { symtab = &((struct cil_root *)ast_node->data)->symtab[CIL_SYM_BLOCKS]; } else { if (call != NULL) { // check macro symtab symtab = &call->macro->symtab[CIL_SYM_BLOCKS]; rc = cil_symtab_get_datum(symtab, tok_current, datum); if (rc == SEPOL_OK) { flavor = ((struct cil_tree_node*)(*datum)->nodes->head->data)->flavor; if (flavor != CIL_BLOCK) { printf("Failed to get block from symtab\n"); rc = SEPOL_ERR; goto exit; } // if in macro, check call parent to verify successful copy to call rc = cil_get_symtab(ast_node->parent->parent, &symtab, CIL_SYM_BLOCKS); if (rc == SEPOL_OK) { rc = cil_symtab_get_datum(symtab, tok_current, datum); flavor = ((struct cil_tree_node*)(*datum)->nodes->head->data)->flavor; if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to get datum from parent symtab of call\n"); goto exit; } else if (flavor != CIL_BLOCK) { printf("Failed to get block from symtab\n"); rc = SEPOL_ERR; goto exit; } } else { cil_log(CIL_ERR, "Failed to get symtab from call parent\n"); goto exit; } } else if (rc == SEPOL_ENOENT) { rc = cil_get_symtab(((struct cil_tree_node*)call->macro->datum.nodes->head->data)->parent, &symtab, CIL_SYM_BLOCKS); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to get datum from parent symtab of macro\n"); goto exit; } } else { goto exit; } } else { if (ast_node->flavor == CIL_TUNABLEIF && macro != NULL) { rc = cil_get_symtab(macro->parent, &symtab, CIL_SYM_BLOCKS); } else { rc = cil_get_symtab(ast_node->parent, &symtab, CIL_SYM_BLOCKS); } if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to get parent symtab, rc: %d\n", rc); goto exit; } } } if (tok_next == NULL) { /*TODO: Should this set rc to SEPOL_ERR? */ /* Cant this be done earlier */ goto exit; } while (tok_current != NULL) { if (tok_next != NULL) { rc = cil_symtab_get_datum(symtab, tok_current, &tmp_datum); if (rc == SEPOL_OK) { flavor = ((struct cil_tree_node*)tmp_datum->nodes->head->data)->flavor; } else { goto exit; } if ((flavor != CIL_BLOCK && ast_node->flavor != CIL_IN) || (flavor == CIL_BLOCK && (((struct cil_block*)tmp_datum)->is_abstract == CIL_TRUE && pass > CIL_PASS_BLKABS ))) { printf("Failed to resolve block: %s\n", tok_current); rc = SEPOL_ERR; goto exit; } symtab = &(((struct cil_block*)tmp_datum)->symtab[CIL_SYM_BLOCKS]); } else { //cil_log(CIL_ERR, "type key: %s\n", tok_current); symtab = &(((struct cil_block*)tmp_datum)->symtab[sym_index]); rc = cil_symtab_get_datum(symtab, tok_current, &tmp_datum); if (rc != SEPOL_OK) { goto exit; } } tok_current = tok_next; tok_next = strtok(NULL, "."); } *datum = tmp_datum; free(name_dup); return SEPOL_OK; exit: free(name_dup); 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) { struct cil_args_resolve *args = extra_args; struct cil_db *db = NULL; struct cil_call *call = NULL; struct cil_tree_node *node = NULL; struct cil_tree_node *macro = NULL; struct cil_tree_node *namespace = NULL; int rc = SEPOL_ERR; char *global_symtab_name = NULL; char first; if (args != NULL) { db = args->db; if (args->callstack != NULL) { call = args->callstack->data; } macro = args->macro; } if (db == NULL || ast_node == NULL || name == NULL) { cil_log(CIL_ERR, "Invalid call to cil_resolve_name\n"); goto exit; } global_symtab_name = name; first = *name; if (first != '.') { if (strrchr(name, '.') == NULL) { symtab_t *symtab = NULL; if (call != NULL) { namespace = ast_node; while (namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_CALL) { namespace = namespace->parent; } if (namespace->flavor == CIL_BLOCK) { rc = cil_get_symtab(namespace, &symtab, sym_index); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to get parent symtab\n"); goto exit; } } else { symtab = &call->macro->symtab[sym_index]; rc = cil_symtab_get_datum(symtab, name, datum); if (rc == SEPOL_OK) { rc = cil_get_symtab(namespace, &symtab, sym_index); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to get parent symtab from call\n"); goto exit; } } } rc = cil_symtab_get_datum(symtab, name, datum); if (rc != SEPOL_OK) { rc = cil_resolve_name_call_args(call, name, sym_index, datum); if (rc == SEPOL_OK) { goto exit; } rc = cil_get_symtab(((struct cil_tree_node*)call->macro->datum.nodes->head->data)->parent, &symtab, sym_index); if (rc != SEPOL_OK) { goto exit; } rc = cil_symtab_get_datum(symtab, name, datum); if (rc == SEPOL_OK) { goto exit; } global_symtab_name = cil_malloc(strlen(name)+2); strcpy(global_symtab_name, "."); strncat(global_symtab_name, name, strlen(name)); } } else { if (ast_node->flavor == CIL_TUNABLEIF && macro != NULL) { rc = cil_get_symtab(macro->parent, &symtab, sym_index); } else { rc = cil_get_symtab(ast_node->parent, &symtab, sym_index); } if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to get parent symtab, rc: %d\n", rc); goto exit; } rc = cil_symtab_get_datum(symtab, name, datum); if (rc != SEPOL_OK) { global_symtab_name = cil_malloc(strlen(name)+2); strcpy(global_symtab_name, "."); strncat(global_symtab_name, name, strlen(name)); } } } else { rc = __cil_resolve_name_helper(ast_node, name, sym_index, args, datum); if (rc != SEPOL_OK) { global_symtab_name = cil_malloc(strlen(name)+2); strcpy(global_symtab_name, "."); strncat(global_symtab_name, name, strlen(name)); } } } first = *global_symtab_name; if (first == '.') { if (strrchr(global_symtab_name, '.') == global_symtab_name) { //Only one dot in name, check global symtabs symtab_t *symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index]; rc = cil_symtab_get_datum(symtab, global_symtab_name+1, datum); if (rc != SEPOL_OK) { free(global_symtab_name); goto exit; } } else { rc = __cil_resolve_name_helper(db->ast->root, global_symtab_name, sym_index, args, datum); if (rc != SEPOL_OK) { free(global_symtab_name); goto exit; } } } if (global_symtab_name != name) { free(global_symtab_name); } rc = SEPOL_OK; exit: if (rc != SEPOL_OK) { cil_log(CIL_WARN, "Failed to resolve %s in %s statement on line %d of %s\n", name, cil_node_to_string(ast_node), ast_node->line, ast_node->path); } if (*datum != NULL) { /* If this datum is an alias, then return the actual node * This depends on aliases already being processed */ node = (*datum)->nodes->head->data; 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; } } } return rc; } libsepol-2.4/cil/src/cil_resolve_ast.h000066400000000000000000000152321246370572200200670ustar00rootroot00000000000000/* * 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_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_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); #endif /* CIL_RESOLVE_AST_H_ */ libsepol-2.4/cil/src/cil_stack.c000066400000000000000000000061701246370572200166420ustar00rootroot00000000000000/* * 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); } 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]; } libsepol-2.4/cil/src/cil_stack.h000066400000000000000000000050071246370572200166450ustar00rootroot00000000000000/* * 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); 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 libsepol-2.4/cil/src/cil_strpool.c000066400000000000000000000065771246370572200172520ustar00rootroot00000000000000/* * 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 "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 hashtab_t cil_strpool_tab = NULL; static unsigned int cil_strpool_hash(hashtab_t h, hashtab_key_t key) { char *p, *keyp; size_t size; unsigned int val; val = 0; keyp = (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 cil_strpool_compare(hashtab_t h __attribute__ ((unused)), hashtab_key_t key1, hashtab_key_t key2) { char *keyp1 = (char*)key1; char *keyp2 = (char*)key2; return strcmp(keyp1, keyp2); } char *cil_strpool_add(const char *str) { struct cil_strpool_entry *strpool_ref = NULL; strpool_ref = hashtab_search(cil_strpool_tab, (hashtab_key_t)str); if (strpool_ref == NULL) { strpool_ref = cil_malloc(sizeof(*strpool_ref)); strpool_ref->str = cil_strdup(str); int rc = hashtab_insert(cil_strpool_tab, (hashtab_key_t)strpool_ref->str, strpool_ref); if (rc != SEPOL_OK) { (*cil_mem_error_handler)(); } } 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) { cil_strpool_tab = hashtab_create(cil_strpool_hash, cil_strpool_compare, CIL_STRPOOL_TABLE_SIZE); if (cil_strpool_tab == NULL) { (*cil_mem_error_handler)(); } } void cil_strpool_destroy(void) { hashtab_map(cil_strpool_tab, cil_strpool_entry_destroy, NULL); hashtab_destroy(cil_strpool_tab); } libsepol-2.4/cil/src/cil_strpool.h000066400000000000000000000034411246370572200172420ustar00rootroot00000000000000/* * 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_ */ libsepol-2.4/cil/src/cil_symtab.c000066400000000000000000000165611246370572200170410ustar00rootroot00000000000000/* * 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_tree.h" #include "cil_symtab.h" #include "cil_mem.h" #include "cil_strpool.h" __attribute__((noreturn)) void cil_symtab_error(const char* msg) { cil_log(CIL_ERR, "%s\n",msg); exit(1); } void cil_symtab_init(symtab_t *symtab, unsigned int size) { int rc = 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; cil_list_init(&datum->nodes, CIL_LIST_ITEM); datum->state = CIL_STATE_ENABLED; } void cil_symtab_datum_destroy(struct cil_symtab_datum *datum) { cil_list_destroy(&datum->nodes, 0); } /* 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; cil_list_append(datum->nodes, CIL_NODE, node); } else if (rc == SEPOL_EEXIST) { cil_list_append(datum->nodes, CIL_NODE, node); } else { cil_symtab_error("Failed to insert datum into hashtab\n"); } return rc; } void cil_symtab_remove_datum_destroy(__attribute__((unused))hashtab_key_t key, hashtab_datum_t datum, __attribute__((unused))void *args) { cil_symtab_datum_destroy((struct cil_symtab_datum *)datum); free(datum); } void cil_symtab_datum_remove(struct cil_symtab_datum *datum, struct cil_tree_node *node) { if (datum->nodes != NULL) { struct cil_list_item *item; struct cil_list_item *previous = NULL; cil_list_for_each(item, datum->nodes) { if (item->data == node) { if (previous == NULL) { datum->nodes->head = item->next; } else { previous->next = item->next; } cil_list_item_destroy(&item, 0); break; } previous = item; } } } 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 || (*datum)->state != CIL_STATE_ENABLED) { 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 hashtab_map(symtab->table, apply, args); } void cil_symtab_destroy(symtab_t *symtab) { if (symtab->table != NULL){ hashtab_destroy(symtab->table); symtab->table = NULL; } } 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) { 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; } libsepol-2.4/cil/src/cil_symtab.h000066400000000000000000000070321246370572200170370ustar00rootroot00000000000000/* * 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" #define CIL_STATE_ENABLED 1 #define CIL_STATE_DISABLED 2 #define CIL_STATE_DISABLING 3 struct cil_symtab_datum { struct cil_list *nodes; char *name; int state; }; #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); int cil_symtab_insert(symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node); void cil_symtab_datum_remove(struct cil_symtab_datum *datum, struct cil_tree_node *node); 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 libsepol-2.4/cil/src/cil_tree.c000066400000000000000000001226601246370572200164770ustar00rootroot00000000000000/* * 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_tree.h" #include "cil_list.h" #include "cil_parser.h" #include "cil_strpool.h" void cil_tree_print_perms_list(struct cil_tree_node *current_perm); void cil_tree_print_classperms(struct cil_classperms *cp); void cil_tree_print_level(struct cil_level *level); void cil_tree_print_levelrange(struct cil_levelrange *lvlrange); void cil_tree_print_context(struct cil_context *context); void cil_tree_print_expr_tree(struct cil_tree_node *expr_root); void cil_tree_print_constrain(struct cil_constrain *cons); void cil_tree_print_node(struct cil_tree_node *node); 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); cil_root_init((struct cil_root **)&new_tree->root->data); *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 *start_node = node; struct cil_tree_node *next = NULL; if (node == NULL) { return; } if (node->cl_head != NULL) { node = node->cl_head; } while (node != start_node) { if (node->cl_head != NULL){ next = node->cl_head; } else { if (node->next == NULL) { next = node->parent; if (node->parent != NULL) { node->parent->cl_head = NULL; } cil_tree_node_destroy(&node); } else { next = node->next; cil_tree_node_destroy(&node); } } node = next; } } 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->path = NULL; *node = new_node; } void cil_tree_node_destroy(struct cil_tree_node **node) { if (node == NULL || *node == NULL) { return; } if ((*node)->flavor >= CIL_MIN_DECLARATIVE) { cil_symtab_datum_remove((*node)->data, *node); struct cil_symtab_datum *datum = (*node)->data; if (datum->nodes != NULL && datum->nodes->head == 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 */ 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_log(CIL_INFO, "Problem at line %d of %s\n", node->line, node->path); 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_log(CIL_INFO, "Problem at line %d of %s\n", node->line, node->path); 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_log(CIL_INFO, "Problem at line %d of %s\n",node->line, node->path); return rc; } } return SEPOL_OK; } /* Copied from cil_policy.c, but changed to prefix -- Need to refactor */ static int cil_expr_to_string(struct cil_list *expr, char **out) { int rc = SEPOL_ERR; struct cil_list_item *curr; char *stack[COND_EXPR_MAXDEPTH] = {}; int pos = 0; cil_list_for_each(curr, expr) { if (pos > COND_EXPR_MAXDEPTH) { rc = SEPOL_ERR; goto exit; } switch (curr->flavor) { case CIL_LIST: rc = cil_expr_to_string(curr->data, &stack[pos]); if (rc != SEPOL_OK) { goto exit; } pos++; break; case CIL_STRING: stack[pos] = curr->data; pos++; break; case CIL_DATUM: stack[pos] = ((struct cil_symtab_datum *)curr->data)->name; pos++; break; case CIL_OP: { int len; char *expr_str; enum cil_flavor op_flavor = *((enum cil_flavor *)curr->data); char *op_str = NULL; if (pos == 0) { rc = SEPOL_ERR; goto exit; } 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: cil_log(CIL_ERR, "Unknown operator in expression\n"); goto exit; break; } if (op_flavor == CIL_NOT) { len = strlen(stack[pos-1]) + strlen(op_str) + 4; expr_str = cil_malloc(len); snprintf(expr_str, len, "(%s %s)", op_str, stack[pos-1]); free(stack[pos-1]); stack[pos-1] = NULL; pos--; } else { if (pos < 2) { rc = SEPOL_ERR; goto exit; } len = strlen(stack[pos-1]) + strlen(stack[pos-2]) + strlen(op_str) + 5; expr_str = cil_malloc(len); snprintf(expr_str, len, "(%s %s %s)", op_str, stack[pos-1], stack[pos-2]); free(stack[pos-2]); free(stack[pos-1]); stack[pos-2] = NULL; stack[pos-1] = NULL; pos -= 2; } stack[pos] = expr_str; pos++; break; } case CIL_CONS_OPERAND: { enum cil_flavor operand_flavor = *((enum cil_flavor *)curr->data); char *operand_str = NULL; 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: cil_log(CIL_ERR, "Unknown operand in expression\n"); goto exit; break; } stack[pos] = operand_str; pos++; break; } default: cil_log(CIL_ERR, "Unknown flavor in expression\n"); goto exit; break; } } *out = stack[0]; return SEPOL_OK; exit: return rc; } void cil_tree_print_expr(struct cil_list *datum_expr, struct cil_list *str_expr) { char *expr_str; cil_log(CIL_INFO, "("); if (datum_expr != NULL) { cil_expr_to_string(datum_expr, &expr_str); } else { cil_expr_to_string(str_expr, &expr_str); } cil_log(CIL_INFO, "%s)", expr_str); free(expr_str); } void cil_tree_print_perms_list(struct cil_tree_node *current_perm) { while (current_perm != NULL) { if (current_perm->flavor == CIL_PERM) { cil_log(CIL_INFO, " %s", ((struct cil_perm *)current_perm->data)->datum.name); } else if (current_perm->flavor == CIL_MAP_PERM) { cil_log(CIL_INFO, " %s", ((struct cil_perm*)current_perm->data)->datum.name); } else { cil_log(CIL_INFO, "\n\n perms list contained unexpected data type: %d\n", current_perm->flavor); break; } current_perm = current_perm->next; } } void cil_tree_print_cats(struct cil_cats *cats) { cil_tree_print_expr(cats->datum_expr, cats->str_expr); } void cil_tree_print_perm_strs(struct cil_list *perm_strs) { struct cil_list_item *curr; if (perm_strs == NULL) { return; } cil_log(CIL_INFO, " ("); cil_list_for_each(curr, perm_strs) { cil_log(CIL_INFO, " %s", (char*)curr->data); } cil_log(CIL_INFO, " )"); } void cil_tree_print_classperms(struct cil_classperms *cp) { if (cp == NULL) { return; } cil_log(CIL_INFO, " class: %s", cp->class_str); cil_log(CIL_INFO, ", perm_strs:"); cil_tree_print_perm_strs(cp->perm_strs); } void cil_tree_print_classperms_set(struct cil_classperms_set *cp_set) { if (cp_set == NULL) { return; } cil_log(CIL_INFO, " %s", cp_set->set_str); } void cil_tree_print_classperms_list(struct cil_list *cp_list) { struct cil_list_item *i; if (cp_list == NULL) { return; } cil_list_for_each(i, cp_list) { if (i->flavor == CIL_CLASSPERMS) { cil_tree_print_classperms(i->data); } else { cil_tree_print_classperms_set(i->data); } } } void cil_tree_print_level(struct cil_level *level) { if (level->sens != NULL) { cil_log(CIL_INFO, " %s", level->sens->datum.name); } else if (level->sens_str != NULL) { cil_log(CIL_INFO, " %s", level->sens_str); } cil_tree_print_cats(level->cats); return; } void cil_tree_print_levelrange(struct cil_levelrange *lvlrange) { cil_log(CIL_INFO, " ("); if (lvlrange->low != NULL) { cil_log(CIL_INFO, " ("); cil_tree_print_level(lvlrange->low); cil_log(CIL_INFO, " )"); } else if (lvlrange->low_str != NULL) { cil_log(CIL_INFO, " %s", lvlrange->low_str); } if (lvlrange->high != NULL) { cil_log(CIL_INFO, " ("); cil_tree_print_level(lvlrange->high); cil_log(CIL_INFO, " )"); } else if (lvlrange->high_str != NULL) { cil_log(CIL_INFO, " %s", lvlrange->high_str); } cil_log(CIL_INFO, " )"); } void cil_tree_print_context(struct cil_context *context) { cil_log(CIL_INFO, " ("); if (context->user != NULL) { cil_log(CIL_INFO, " %s", context->user->datum.name); } else if (context->user_str != NULL) { cil_log(CIL_INFO, " %s", context->user_str); } if (context->role != NULL) { cil_log(CIL_INFO, " %s", context->role->datum.name); } else if (context->role_str != NULL) { cil_log(CIL_INFO, " %s", context->role_str); } if (context->type != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)context->type)->name); } else if (context->type_str != NULL) { cil_log(CIL_INFO, " %s", context->type_str); } if (context->range != NULL) { cil_tree_print_levelrange(context->range); } else if (context->range_str != NULL) { cil_log(CIL_INFO, " %s", context->range_str); } cil_log(CIL_INFO, " )"); return; } void cil_tree_print_constrain(struct cil_constrain *cons) { cil_tree_print_classperms_list(cons->classperms); cil_tree_print_expr(cons->datum_expr, cons->str_expr); cil_log(CIL_INFO, "\n"); } void cil_tree_print_node(struct cil_tree_node *node) { if (node->data == NULL) { cil_log(CIL_INFO, "FLAVOR: %d", node->flavor); return; } else { switch( node->flavor ) { case CIL_BLOCK: { struct cil_block *block = node->data; cil_log(CIL_INFO, "BLOCK: %s\n", block->datum.name); return; } case CIL_BLOCKINHERIT: { struct cil_blockinherit *inherit = node->data; cil_log(CIL_INFO, "BLOCKINHERIT: %s\n", inherit->block_str); return; } case CIL_BLOCKABSTRACT: { struct cil_blockabstract *abstract = node->data; cil_log(CIL_INFO, "BLOCKABSTRACT: %s\n", abstract->block_str); return; } case CIL_IN: { struct cil_in *in = node->data; cil_log(CIL_INFO, "IN: %s\n", in->block_str); return; } case CIL_USER: { struct cil_user *user = node->data; cil_log(CIL_INFO, "USER: %s\n", user->datum.name); return; } case CIL_TYPE: { struct cil_type *type = node->data; cil_log(CIL_INFO, "TYPE: %s\n", type->datum.name); return; } case CIL_TYPEATTRIBUTESET: { struct cil_typeattributeset *attr = node->data; cil_log(CIL_INFO, "(TYPEATTRIBUTESET %s ", attr->attr_str); cil_tree_print_expr(attr->datum_expr, attr->str_expr); cil_log(CIL_INFO, "\n"); return; } case CIL_TYPEATTRIBUTE: { struct cil_typeattribute *attr = node->data; cil_log(CIL_INFO, "TYPEATTRIBUTE: %s\n", attr->datum.name); return; } case CIL_ROLE: { struct cil_role *role = node->data; cil_log(CIL_INFO, "ROLE: %s\n", role->datum.name); return; } case CIL_USERROLE: { struct cil_userrole *userrole = node->data; cil_log(CIL_INFO, "USERROLE:"); if (userrole->user != NULL) { cil_log(CIL_INFO, " %s", userrole->user->datum.name); } else if (userrole->user_str != NULL) { cil_log(CIL_INFO, " %s", userrole->user_str); } if (userrole->role != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)userrole->role)->name); } else if (userrole->role_str != NULL) { cil_log(CIL_INFO, " %s", userrole->role_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_USERLEVEL: { struct cil_userlevel *usrlvl = node->data; cil_log(CIL_INFO, "USERLEVEL:"); if (usrlvl->user_str != NULL) { cil_log(CIL_INFO, " %s", usrlvl->user_str); } if (usrlvl->level != NULL) { cil_log(CIL_INFO, " ("); cil_tree_print_level(usrlvl->level); cil_log(CIL_INFO, " )"); } else if (usrlvl->level_str != NULL) { cil_log(CIL_INFO, " %s", usrlvl->level_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_USERRANGE: { struct cil_userrange *userrange = node->data; cil_log(CIL_INFO, "USERRANGE:"); if (userrange->user_str != NULL) { cil_log(CIL_INFO, " %s", userrange->user_str); } if (userrange->range != NULL) { cil_log(CIL_INFO, " ("); cil_tree_print_levelrange(userrange->range); cil_log(CIL_INFO, " )"); } else if (userrange->range_str != NULL) { cil_log(CIL_INFO, " %s", userrange->range_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_USERBOUNDS: { struct cil_bounds *bnds = node->data; cil_log(CIL_INFO, "USERBOUNDS: user: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); return; } case CIL_ROLETYPE: { struct cil_roletype *roletype = node->data; struct cil_symtab_datum *datum = NULL; cil_log(CIL_INFO, "ROLETYPE:"); if (roletype->role != NULL) { datum = roletype->role; cil_log(CIL_INFO, " %s", datum->name); } else if (roletype->role_str != NULL) { cil_log(CIL_INFO, " %s", roletype->role_str); } if (roletype->type != NULL) { datum = roletype->type; cil_log(CIL_INFO, " %s", datum->name); } else if (roletype->type_str != NULL) { cil_log(CIL_INFO, " %s", roletype->type_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_ROLETRANSITION: { struct cil_roletransition *roletrans = node->data; cil_log(CIL_INFO, "ROLETRANSITION:"); if (roletrans->src != NULL) { cil_log(CIL_INFO, " %s", roletrans->src->datum.name); } else { cil_log(CIL_INFO, " %s", roletrans->src_str); } if (roletrans->tgt != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)roletrans->tgt)->name); } else { cil_log(CIL_INFO, " %s", roletrans->tgt_str); } if (roletrans->obj != NULL) { cil_log(CIL_INFO, " %s", roletrans->obj->datum.name); } else { cil_log(CIL_INFO, " %s", roletrans->obj_str); } if (roletrans->result != NULL) { cil_log(CIL_INFO, " %s\n", roletrans->result->datum.name); } else { cil_log(CIL_INFO, " %s\n", roletrans->result_str); } return; } case CIL_ROLEALLOW: { struct cil_roleallow *roleallow = node->data; cil_log(CIL_INFO, "ROLEALLOW:"); if (roleallow->src != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->src)->name); } else { cil_log(CIL_INFO, " %s", roleallow->src_str); } if (roleallow->tgt != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->tgt)->name); } else { cil_log(CIL_INFO, " %s", roleallow->tgt_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_ROLEATTRIBUTESET: { struct cil_roleattributeset *attr = node->data; cil_log(CIL_INFO, "(ROLEATTRIBUTESET %s ", attr->attr_str); cil_tree_print_expr(attr->datum_expr, attr->str_expr); cil_log(CIL_INFO, "\n"); return; } case CIL_ROLEATTRIBUTE: { struct cil_roleattribute *attr = node->data; cil_log(CIL_INFO, "ROLEATTRIBUTE: %s\n", attr->datum.name); return; } case CIL_ROLEBOUNDS: { struct cil_bounds *bnds = node->data; cil_log(CIL_INFO, "ROLEBOUNDS: role: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); return; } case CIL_CLASS: { struct cil_class *cls = node->data; cil_log(CIL_INFO, "CLASS: %s ", cls->datum.name); if (cls->common != NULL) { cil_log(CIL_INFO, "inherits: %s ", cls->common->datum.name); } cil_log(CIL_INFO, "("); cil_tree_print_perms_list(node->cl_head); cil_log(CIL_INFO, " )"); return; } case CIL_CLASSORDER: { struct cil_classorder *classorder = node->data; struct cil_list_item *class; if (classorder->class_list_str == NULL) { cil_log(CIL_INFO, "CLASSORDER: ()\n"); return; } cil_log(CIL_INFO, "CLASSORDER: ("); cil_list_for_each(class, classorder->class_list_str) { cil_log(CIL_INFO, " %s", (char*)class->data); } cil_log(CIL_INFO, " )\n"); return; } case CIL_COMMON: { struct cil_class *common = node->data; cil_log(CIL_INFO, "COMMON: %s (", common->datum.name); cil_tree_print_perms_list(node->cl_head); cil_log(CIL_INFO, " )"); return; } case CIL_CLASSCOMMON: { struct cil_classcommon *clscom = node->data; cil_log(CIL_INFO, "CLASSCOMMON: class: %s, common: %s\n", clscom->class_str, clscom->common_str); return; } case CIL_CLASSPERMISSION: { struct cil_classpermission *cp = node->data; cil_log(CIL_INFO, "CLASSPERMISSION: %s", cp->datum.name); cil_log(CIL_INFO, "\n"); return; } case CIL_CLASSPERMISSIONSET: { struct cil_classpermissionset *cps = node->data; cil_log(CIL_INFO, "CLASSPERMISSIONSET: %s", cps->set_str); cil_tree_print_classperms_list(cps->classperms); cil_log(CIL_INFO, "\n"); return; } case CIL_MAP_CLASS: { struct cil_class *cm = node->data; cil_log(CIL_INFO, "MAP_CLASS: %s", cm->datum.name); cil_log(CIL_INFO, " ("); cil_tree_print_perms_list(node->cl_head); cil_log(CIL_INFO, " )\n"); return; } case CIL_MAP_PERM: { struct cil_perm *cmp = node->data; cil_log(CIL_INFO, "MAP_PERM: %s", cmp->datum.name); if (cmp->classperms == NULL) { cil_log(CIL_INFO, " perms: ()"); return; } cil_log(CIL_INFO, " kernel class perms: ("); cil_tree_print_classperms_list(cmp->classperms); cil_log(CIL_INFO, " )\n"); return; } case CIL_CLASSMAPPING: { struct cil_classmapping *mapping = node->data; cil_log(CIL_INFO, "CLASSMAPPING: map class: %s, map perm: %s,", mapping->map_class_str, mapping->map_perm_str); cil_log(CIL_INFO, " ("); cil_tree_print_classperms_list(mapping->classperms); cil_log(CIL_INFO, " )\n"); return; } case CIL_BOOL: { struct cil_bool *boolean = node->data; cil_log(CIL_INFO, "BOOL: %s, value: %d\n", boolean->datum.name, boolean->value); return; } case CIL_TUNABLE: { struct cil_tunable *tunable = node->data; cil_log(CIL_INFO, "TUNABLE: %s, value: %d\n", tunable->datum.name, tunable->value); return; } case CIL_BOOLEANIF: { struct cil_booleanif *bif = node->data; cil_log(CIL_INFO, "(BOOLEANIF "); cil_tree_print_expr(bif->datum_expr, bif->str_expr); cil_log(CIL_INFO, " )\n"); return; } case CIL_TUNABLEIF: { struct cil_tunableif *tif = node->data; cil_log(CIL_INFO, "(TUNABLEIF "); cil_tree_print_expr(tif->datum_expr, tif->str_expr); cil_log(CIL_INFO, " )\n"); return; } case CIL_CONDBLOCK: { struct cil_condblock *cb = node->data; if (cb->flavor == CIL_CONDTRUE) { cil_log(CIL_INFO, "true\n"); } else if (cb->flavor == CIL_CONDFALSE) { cil_log(CIL_INFO, "false\n"); } return; } case CIL_ALL: cil_log(CIL_INFO, "all"); return; case CIL_AND: cil_log(CIL_INFO, "&&"); return; case CIL_OR: cil_log(CIL_INFO, "|| "); return; case CIL_NOT: cil_log(CIL_INFO, "!"); return; case CIL_EQ: cil_log(CIL_INFO, "=="); return; case CIL_NEQ: cil_log(CIL_INFO, "!="); return; case CIL_TYPEALIAS: { struct cil_alias *alias = node->data; cil_log(CIL_INFO, "TYPEALIAS: %s\n", alias->datum.name); return; } case CIL_TYPEALIASACTUAL: { struct cil_aliasactual *aliasactual = node->data; cil_log(CIL_INFO, "TYPEALIASACTUAL: type: %s, alias: %s\n", aliasactual->alias_str, aliasactual->actual_str); return; } case CIL_TYPEBOUNDS: { struct cil_bounds *bnds = node->data; cil_log(CIL_INFO, "TYPEBOUNDS: type: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); return; } case CIL_TYPEPERMISSIVE: { struct cil_typepermissive *typeperm = node->data; if (typeperm->type != NULL) { cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", ((struct cil_symtab_datum *)typeperm->type)->name); } else { cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", typeperm->type_str); } return; } case CIL_NAMETYPETRANSITION: { struct cil_nametypetransition *nametypetrans = node->data; cil_log(CIL_INFO, "TYPETRANSITION:"); if (nametypetrans->src != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->src)->name); } else { cil_log(CIL_INFO, " %s", nametypetrans->src_str); } if (nametypetrans->tgt != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->tgt)->name); } else { cil_log(CIL_INFO, " %s", nametypetrans->tgt_str); } if (nametypetrans->obj != NULL) { cil_log(CIL_INFO, " %s", nametypetrans->obj->datum.name); } else { cil_log(CIL_INFO, " %s", nametypetrans->obj_str); } cil_log(CIL_INFO, " %s\n", nametypetrans->name_str); if (nametypetrans->result != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->result)->name); } else { cil_log(CIL_INFO, " %s", nametypetrans->result_str); } return; } case CIL_RANGETRANSITION: { struct cil_rangetransition *rangetrans = node->data; cil_log(CIL_INFO, "RANGETRANSITION:"); if (rangetrans->src != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->src)->name); } else { cil_log(CIL_INFO, " %s", rangetrans->src_str); } if (rangetrans->exec != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->exec)->name); } else { cil_log(CIL_INFO, " %s", rangetrans->exec_str); } if (rangetrans->obj != NULL) { cil_log(CIL_INFO, " %s", rangetrans->obj->datum.name); } else { cil_log(CIL_INFO, " %s", rangetrans->obj_str); } if (rangetrans->range != NULL) { cil_log(CIL_INFO, " ("); cil_tree_print_levelrange(rangetrans->range); cil_log(CIL_INFO, " )"); } else { cil_log(CIL_INFO, " %s", rangetrans->range_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_AVRULE: { struct cil_avrule *rule = node->data; switch (rule->rule_kind) { case CIL_AVRULE_ALLOWED: cil_log(CIL_INFO, "ALLOW:"); break; case CIL_AVRULE_AUDITALLOW: cil_log(CIL_INFO, "AUDITALLOW:"); break; case CIL_AVRULE_DONTAUDIT: cil_log(CIL_INFO, "DONTAUDIT:"); break; case CIL_AVRULE_NEVERALLOW: cil_log(CIL_INFO, "NEVERALLOW:"); break; } if (rule->src != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->src)->name); } else { cil_log(CIL_INFO, " %s", rule->src_str); } if (rule->tgt != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->tgt)->name); } else { cil_log(CIL_INFO, " %s", rule->tgt_str); } cil_tree_print_classperms_list(rule->classperms); cil_log(CIL_INFO, "\n"); return; } case CIL_TYPE_RULE: { struct cil_type_rule *rule = node->data; switch (rule->rule_kind) { case CIL_TYPE_TRANSITION: cil_log(CIL_INFO, "TYPETRANSITION:"); break; case CIL_TYPE_MEMBER: cil_log(CIL_INFO, "TYPEMEMBER:"); break; case CIL_TYPE_CHANGE: cil_log(CIL_INFO, "TYPECHANGE:"); break; } if (rule->src != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->src)->name); } else { cil_log(CIL_INFO, " %s", rule->src_str); } if (rule->tgt != NULL) { cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->tgt)->name); } else { cil_log(CIL_INFO, " %s", rule->tgt_str); } if (rule->obj != NULL) { cil_log(CIL_INFO, " %s", rule->obj->datum.name); } else { cil_log(CIL_INFO, " %s", rule->obj_str); } if (rule->result != NULL) { cil_log(CIL_INFO, " %s\n", ((struct cil_symtab_datum *)rule->result)->name); } else { cil_log(CIL_INFO, " %s\n", rule->result_str); } return; } case CIL_SENS: { struct cil_sens *sens = node->data; cil_log(CIL_INFO, "SENSITIVITY: %s\n", sens->datum.name); return; } case CIL_SENSALIAS: { struct cil_alias *alias = node->data; cil_log(CIL_INFO, "SENSITIVITYALIAS: %s\n", alias->datum.name); return; } case CIL_SENSALIASACTUAL: { struct cil_aliasactual *aliasactual = node->data; cil_log(CIL_INFO, "SENSITIVITYALIAS: alias: %s, sensitivity: %s\n", aliasactual->alias_str, aliasactual->actual_str); return; } case CIL_CAT: { struct cil_cat *cat = node->data; cil_log(CIL_INFO, "CATEGORY: %s\n", cat->datum.name); return; } case CIL_CATALIAS: { struct cil_alias *alias = node->data; cil_log(CIL_INFO, "CATEGORYALIAS: %s\n", alias->datum.name); return; } case CIL_CATALIASACTUAL: { struct cil_aliasactual *aliasactual = node->data; cil_log(CIL_INFO, "CATEGORYALIAS: alias %s, category: %s\n", aliasactual->alias_str, aliasactual->actual_str); return; } case CIL_CATSET: { struct cil_catset *catset = node->data; cil_log(CIL_INFO, "CATSET: %s ",catset->datum.name); cil_tree_print_cats(catset->cats); return; } case CIL_CATORDER: { struct cil_catorder *catorder = node->data; struct cil_list_item *cat; if (catorder->cat_list_str == NULL) { cil_log(CIL_INFO, "CATORDER: ()\n"); return; } cil_log(CIL_INFO, "CATORDER: ("); cil_list_for_each(cat, catorder->cat_list_str) { cil_log(CIL_INFO, " %s", (char*)cat->data); } cil_log(CIL_INFO, " )\n"); return; } case CIL_SENSCAT: { struct cil_senscat *senscat = node->data; cil_log(CIL_INFO, "SENSCAT: sens:"); if (senscat->sens_str != NULL) { cil_log(CIL_INFO, " %s ", senscat->sens_str); } else { cil_log(CIL_INFO, " [processed]"); } cil_tree_print_cats(senscat->cats); return; } case CIL_SENSITIVITYORDER: { struct cil_sensorder *sensorder = node->data; struct cil_list_item *sens; cil_log(CIL_INFO, "SENSITIVITYORDER: ("); if (sensorder->sens_list_str != NULL) { cil_list_for_each(sens, sensorder->sens_list_str) { if (sens->flavor == CIL_LIST) { struct cil_list_item *sub; cil_log(CIL_INFO, " ("); cil_list_for_each(sub, (struct cil_list*)sens->data) { cil_log(CIL_INFO, " %s", (char*)sub->data); } cil_log(CIL_INFO, " )"); } else { cil_log(CIL_INFO, " %s", (char*)sens->data); } } } cil_log(CIL_INFO, " )\n"); return; } case CIL_LEVEL: { struct cil_level *level = node->data; cil_log(CIL_INFO, "LEVEL %s:", level->datum.name); cil_tree_print_level(level); cil_log(CIL_INFO, "\n"); return; } case CIL_LEVELRANGE: { struct cil_levelrange *lvlrange = node->data; cil_log(CIL_INFO, "LEVELRANGE %s:", lvlrange->datum.name); cil_tree_print_levelrange(lvlrange); cil_log(CIL_INFO, "\n"); return; } case CIL_CONSTRAIN: { struct cil_constrain *cons = node->data; cil_log(CIL_INFO, "CONSTRAIN: ("); cil_tree_print_constrain(cons); return; } case CIL_MLSCONSTRAIN: { struct cil_constrain *cons = node->data; cil_log(CIL_INFO, "MLSCONSTRAIN: ("); cil_tree_print_constrain(cons); return; } case CIL_VALIDATETRANS: { struct cil_validatetrans *vt = node->data; cil_log(CIL_INFO, "(VALIDATETRANS "); if (vt->class != NULL) { cil_log(CIL_INFO, "%s ", vt->class->datum.name); } else if (vt->class_str != NULL) { cil_log(CIL_INFO, "%s ", vt->class_str); } cil_tree_print_expr(vt->datum_expr, vt->str_expr); cil_log(CIL_INFO, ")\n"); return; } case CIL_MLSVALIDATETRANS: { struct cil_validatetrans *vt = node->data; cil_log(CIL_INFO, "(MLSVALIDATETRANS "); if (vt->class != NULL) { cil_log(CIL_INFO, "%s ", vt->class->datum.name); } else if (vt->class_str != NULL) { cil_log(CIL_INFO, "%s ", vt->class_str); } cil_tree_print_expr(vt->datum_expr, vt->str_expr); cil_log(CIL_INFO, ")\n"); return; } case CIL_CONTEXT: { struct cil_context *context = node->data; cil_log(CIL_INFO, "CONTEXT %s:", context->datum.name); cil_tree_print_context(context); cil_log(CIL_INFO, "\n"); return; } case CIL_FILECON: { struct cil_filecon *filecon = node->data; cil_log(CIL_INFO, "FILECON:"); cil_log(CIL_INFO, " %s %d", filecon->path_str, filecon->type); if (filecon->context_str != NULL) { cil_log(CIL_INFO, " %s", filecon->context_str); } else if (filecon->context != NULL) { cil_tree_print_context(filecon->context); } else if (filecon->context_str != NULL) { cil_log(CIL_INFO, " %s", filecon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_PORTCON: { struct cil_portcon *portcon = node->data; cil_log(CIL_INFO, "PORTCON:"); if (portcon->proto == CIL_PROTOCOL_UDP) { cil_log(CIL_INFO, " udp"); } else if (portcon->proto == CIL_PROTOCOL_TCP) { cil_log(CIL_INFO, " tcp"); } cil_log(CIL_INFO, " (%d %d)", portcon->port_low, portcon->port_high); if (portcon->context != NULL) { cil_tree_print_context(portcon->context); } else if (portcon->context_str != NULL) { cil_log(CIL_INFO, " %s", portcon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_NODECON: { struct cil_nodecon *nodecon = node->data; char buf[256]; cil_log(CIL_INFO, "NODECON:"); if (nodecon->addr) { inet_ntop(nodecon->addr->family, &nodecon->addr->ip, buf, 256); cil_log(CIL_INFO, " %s", buf); } else { cil_log(CIL_INFO, " %s", nodecon->addr_str); } if (nodecon->mask) { inet_ntop(nodecon->mask->family, &nodecon->mask->ip, buf, 256); cil_log(CIL_INFO, " %s", buf); } else { cil_log(CIL_INFO, " %s", nodecon->mask_str); } if (nodecon->context != NULL) { cil_tree_print_context(nodecon->context); } else if (nodecon->context_str != NULL) { cil_log(CIL_INFO, " %s", nodecon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_GENFSCON: { struct cil_genfscon *genfscon = node->data; cil_log(CIL_INFO, "GENFSCON:"); cil_log(CIL_INFO, " %s %s", genfscon->fs_str, genfscon->path_str); if (genfscon->context != NULL) { cil_tree_print_context(genfscon->context); } else if (genfscon->context_str != NULL) { cil_log(CIL_INFO, " %s", genfscon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_NETIFCON: { struct cil_netifcon *netifcon = node->data; cil_log(CIL_INFO, "NETIFCON %s", netifcon->interface_str); if (netifcon->if_context != NULL) { cil_tree_print_context(netifcon->if_context); } else if (netifcon->if_context_str != NULL) { cil_log(CIL_INFO, " %s", netifcon->if_context_str); } if (netifcon->packet_context != NULL) { cil_tree_print_context(netifcon->packet_context); } else if (netifcon->packet_context_str != NULL) { cil_log(CIL_INFO, " %s", netifcon->packet_context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_PIRQCON: { struct cil_pirqcon *pirqcon = node->data; cil_log(CIL_INFO, "PIRQCON %d", pirqcon->pirq); if (pirqcon->context != NULL) { cil_tree_print_context(pirqcon->context); } else { cil_log(CIL_INFO, " %s", pirqcon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_IOMEMCON: { struct cil_iomemcon *iomemcon = node->data; cil_log(CIL_INFO, "IOMEMCON ( %d %d )", iomemcon->iomem_low, iomemcon->iomem_high); if (iomemcon->context != NULL) { cil_tree_print_context(iomemcon->context); } else { cil_log(CIL_INFO, " %s", iomemcon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_IOPORTCON: { struct cil_ioportcon *ioportcon = node->data; cil_log(CIL_INFO, "IOPORTCON ( %d %d )", ioportcon->ioport_low, ioportcon->ioport_high); if (ioportcon->context != NULL) { cil_tree_print_context(ioportcon->context); } else { cil_log(CIL_INFO, " %s", ioportcon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_PCIDEVICECON: { struct cil_pcidevicecon *pcidevicecon = node->data; cil_log(CIL_INFO, "PCIDEVICECON %d", pcidevicecon->dev); if (pcidevicecon->context != NULL) { cil_tree_print_context(pcidevicecon->context); } else { cil_log(CIL_INFO, " %s", pcidevicecon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_FSUSE: { struct cil_fsuse *fsuse = node->data; cil_log(CIL_INFO, "FSUSE: "); if (fsuse->type == CIL_FSUSE_XATTR) { cil_log(CIL_INFO, "xattr "); } else if (fsuse->type == CIL_FSUSE_TASK) { cil_log(CIL_INFO, "task "); } else if (fsuse->type == CIL_FSUSE_TRANS) { cil_log(CIL_INFO, "trans "); } else { cil_log(CIL_INFO, "unknown "); } cil_log(CIL_INFO, "%s ", fsuse->fs_str); if (fsuse->context != NULL) { cil_tree_print_context(fsuse->context); } else { cil_log(CIL_INFO, " %s", fsuse->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_SID: { struct cil_sid *sid = node->data; cil_log(CIL_INFO, "SID: %s\n", sid->datum.name); return; } case CIL_SIDCONTEXT: { struct cil_sidcontext *sidcon = node->data; cil_log(CIL_INFO, "SIDCONTEXT: %s", sidcon->sid_str); if (sidcon->context != NULL) { cil_tree_print_context(sidcon->context); } else { cil_log(CIL_INFO, " %s", sidcon->context_str); } cil_log(CIL_INFO, "\n"); return; } case CIL_SIDORDER: { struct cil_sidorder *sidorder = node->data; struct cil_list_item *sid; if (sidorder->sid_list_str == NULL) { cil_log(CIL_INFO, "SIDORDER: ()\n"); return; } cil_log(CIL_INFO, "SIDORDER: ("); cil_list_for_each(sid, sidorder->sid_list_str) { cil_log(CIL_INFO, " %s", (char*)sid->data); } cil_log(CIL_INFO, " )\n"); return; } case CIL_POLICYCAP: { struct cil_policycap *polcap = node->data; cil_log(CIL_INFO, "POLICYCAP: %s\n", polcap->datum.name); return; } case CIL_MACRO: { struct cil_macro *macro = node->data; cil_log(CIL_INFO, "MACRO %s:", macro->datum.name); if (macro->params != NULL && macro->params->head != NULL) { struct cil_list_item *curr_param; cil_log(CIL_INFO, " parameters: ("); cil_list_for_each(curr_param, macro->params) { cil_log(CIL_INFO, " flavor: %d, string: %s;", ((struct cil_param*)curr_param->data)->flavor, ((struct cil_param*)curr_param->data)->str); } cil_log(CIL_INFO, " )"); } cil_log(CIL_INFO, "\n"); return; } case CIL_CALL: { struct cil_call *call = node->data; cil_log(CIL_INFO, "CALL: macro name:"); if (call->macro != NULL) { cil_log(CIL_INFO, " %s", call->macro->datum.name); } else { cil_log(CIL_INFO, " %s", call->macro_str); } if (call->args != NULL) { cil_log(CIL_INFO, ", args: ( "); struct cil_list_item *item; cil_list_for_each(item, call->args) { struct cil_symtab_datum *datum = ((struct cil_args*)item->data)->arg; if (datum != NULL) { if (datum->nodes != NULL && datum->nodes->head != NULL) { cil_tree_print_node((struct cil_tree_node*)datum->nodes->head->data); } } else if (((struct cil_args*)item->data)->arg_str != NULL) { switch (item->flavor) { case CIL_TYPE: cil_log(CIL_INFO, "type:"); break; case CIL_USER: cil_log(CIL_INFO, "user:"); break; case CIL_ROLE: cil_log(CIL_INFO, "role:"); break; case CIL_SENS: cil_log(CIL_INFO, "sensitivity:"); break; case CIL_CAT: cil_log(CIL_INFO, "category:"); break; case CIL_CATSET: cil_log(CIL_INFO, "categoryset:"); break; case CIL_LEVEL: cil_log(CIL_INFO, "level:"); break; case CIL_CLASS: cil_log(CIL_INFO, "class:"); break; default: break; } cil_log(CIL_INFO, "%s ", ((struct cil_args*)item->data)->arg_str); } } cil_log(CIL_INFO, ")"); } cil_log(CIL_INFO, "\n"); return; } case CIL_OPTIONAL: { struct cil_optional *optional = node->data; cil_log(CIL_INFO, "OPTIONAL: %s\n", optional->datum.name); return; } case CIL_IPADDR: { struct cil_ipaddr *ipaddr = node->data; char buf[256]; inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256); cil_log(CIL_INFO, "IPADDR %s: %s\n", ipaddr->datum.name, buf); break; } default : { cil_log(CIL_INFO, "CIL FLAVOR: %d\n", node->flavor); return; } } } } void cil_tree_print(struct cil_tree_node *tree, uint32_t depth) { struct cil_tree_node *current = NULL; current = tree; uint32_t x = 0; if (current != NULL) { if (current->cl_head == NULL) { if (current->flavor == CIL_NODE) { if (current->parent->cl_head == current) { cil_log(CIL_INFO, "%s", (char*)current->data); } else { cil_log(CIL_INFO, " %s", (char*)current->data); } } else if (current->flavor != CIL_PERM) { for (x = 0; xparent != NULL) { cil_log(CIL_INFO, "\n"); for (x = 0; xflavor != CIL_NODE) { cil_tree_print_node(current); } } cil_tree_print(current->cl_head, depth + 1); } if (current->next == NULL) { if ((current->parent != NULL) && (current->parent->cl_tail == current) && (current->parent->parent != NULL)) { if (current->flavor == CIL_PERM) { cil_log(CIL_INFO, ")\n"); } else if (current->flavor != CIL_NODE) { for (x = 0; xparent != NULL) && (current->parent->parent == NULL)) cil_log(CIL_INFO, "\n\n"); } else { cil_tree_print(current->next, depth); } } else { cil_log(CIL_INFO, "Tree is NULL\n"); } } libsepol-2.4/cil/src/cil_tree.h000066400000000000000000000056611246370572200165050ustar00rootroot00000000000000/* * 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; char *path; void *data; }; 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); void cil_tree_print(struct cil_tree_node *tree, uint32_t depth); //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_ */ libsepol-2.4/cil/src/cil_verify.c000066400000000000000000001122001246370572200170310ustar00rootroot00000000000000/* * 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_verify.h" int __cil_verify_name(const char *name) { int rc = SEPOL_ERR; int len = strlen(name); int i = 0; 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; } 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; } } 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[], int len) { int rc = SEPOL_ERR; int num_extras = 0; struct cil_tree_node *c = parse_current; int i = 0; while (i < len) { if ((s[i] & CIL_SYN_END) && c == NULL) { break; } if (s[i] & CIL_SYN_N_LISTS || s[i] & CIL_SYN_N_STRINGS) { if (c == NULL) { if (num_extras > 0) { i++; continue; } else { goto exit; } } else if ((s[i] & CIL_SYN_N_LISTS) && (c->data == NULL && c->cl_head != NULL)) { c = c->next; num_extras++; continue; } else if ((s[i] & CIL_SYN_N_STRINGS) && (c->data != NULL && c->cl_head == NULL)) { c = c->next; num_extras++; continue; } } if (c == NULL) { goto exit; } if (s[i] & CIL_SYN_STRING) { if (c->data != NULL && c->cl_head == NULL) { c = c->next; i++; continue; } } if (s[i] & CIL_SYN_LIST) { if (c->data == NULL && c->cl_head != NULL) { c = c->next; i++; continue; } } if (s[i] & CIL_SYN_EMPTY_LIST) { if (c->data == NULL && c->cl_head == NULL) { c = c->next; i++; continue; } } goto exit; } return SEPOL_OK; exit: cil_log(CIL_ERR, "Invalid syntax\n"); return rc; } 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) { cil_log(CIL_ERR,"Operator (%s) only valid for catset 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_MLSVALIDATETRANS) { cil_log(CIL_ERR, "u3, r3, and t3 can only be used with mlsvalidatetrans rules\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_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list) { struct cil_list_item *i; cil_list_for_each(i, datum_list) { if (i->flavor == CIL_DATUM) { struct cil_symtab_datum *d = i->data; if (d == datum) { cil_log(CIL_ERR,"Self-reference found for %s\n",datum->name); return SEPOL_ERR; } } else if (i->flavor == CIL_LIST) { int rc = cil_verify_no_self_reference(datum, i->data); if (rc != SEPOL_OK) { return SEPOL_ERR; } } } return SEPOL_OK; } 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_log(CIL_ERR, "SID %s not in sidorder statement at line %d of %s\n", sid->datum.name, node->line, node->path); return SEPOL_ERR; } } else if (node->flavor == CIL_CLASS) { struct cil_class *class = node->data; if (class->ordered == CIL_FALSE) { cil_log(CIL_ERR, "Class %s not in classorder statement at line %d of %s\n", class->datum.name, node->line, node->path); return SEPOL_ERR; } } else if (node->flavor == CIL_CAT) { struct cil_cat *cat = node->data; if (cat->ordered == CIL_FALSE) { cil_log(CIL_ERR, "Category %s not in categoryorder statement at line %d of %s\n", cat->datum.name, node->line, node->path); return SEPOL_ERR; } } else if (node->flavor == CIL_SENS) { struct cil_sens *sens = node->data; if (sens->ordered == CIL_FALSE) { cil_log(CIL_ERR, "Sensitivity %s not in sensitivityorder statement at line %d of %s\n", sens->datum.name, node->line, node->path); 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_log(CIL_ERR, "No context assigned to SID %s declared at line %d in %s\n",sid->datum.name, node->line, node->path); rc = SEPOL_ERR; } } return rc; } 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; } 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; } 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; } 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; } 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; } 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; } 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_log(CIL_ERR, "Invalid named range at line %d of %s\n", node->line, node->path); return rc; } int __cil_verify_user(struct cil_db *db, 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++; } } /* 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_log(CIL_ERR, "Invalid user at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid role at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid type at line %d of %s\n", node->line, node->path); return rc; } 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) { cil_list_for_each(curr, user->roles) { struct cil_role *userrole = curr->data; if (userrole == role) { break; } } if (curr == NULL) { 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 (!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; } 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_log(CIL_ERR, "Invalid named context at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Duplicate rule defined on line %d of %s\n", node->line, node->path); rc = SEPOL_ERR; goto exit; } } return SEPOL_OK; exit: cil_log(CIL_ERR, "Invalid rule at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Neverallow found in tunableif block (treated as a booleanif due to preserve-tunables) at line %d or %s\n", node->line, node->path); } else { cil_log(CIL_ERR, "Neverallow found in booleanif block at line %d or %s\n", node->line, node->path); } 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_log(CIL_ERR, "Invalid %s statement in tunableif (treated as a booleanif due to preserve-tunables) at line %d of %s\n", flavor, node->line, node->path); } else { cil_log(CIL_ERR, "Invalid %s statement in booleanif at line %d of %s\n", flavor, node->line, node->path); } goto exit; } } rc = SEPOL_OK; exit: return rc; } 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_log(CIL_ERR, "Invalid tunableif (treated as a booleanif due to preserve-tunables) at line %d of %s\n", node->line, node->path); } else { cil_log(CIL_ERR, "Invalid booleanif at line %d of %s\n", node->line, node->path); } return rc; } 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_log(CIL_ERR, "Invalid netifcon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid genfscon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid filecon at line %d of %s\n", node->line, node->path); goto exit; } } return SEPOL_OK; exit: return rc; } 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_log(CIL_ERR, "Invalid nodecon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid portcon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid pirqcon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid iomemcon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid ioportcon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid pcidevicecon at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid fsuse at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid class at line %d of %s\n", node->line, node->path); return rc; } 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_log(CIL_ERR, "Invalid policycap (%s) at line %d of %s\n", (const char*)polcap->datum.name, node->line, node->path); 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 state = 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_OPTIONAL) { state = ((struct cil_symtab_datum *)node->data)->state; if (state == CIL_STATE_DISABLED) { *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_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(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_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_FSUSE: rc = __cil_verify_fsuse(db, node); break; case CIL_RANGETRANSITION: rc = SEPOL_OK; break; default: rc = SEPOL_OK; break; } break; } default: rc = SEPOL_ERR; } exit: return rc; } static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symtab_datum *orig) { 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) { return SEPOL_OK; } else { /* MAP */ struct cil_list_item *i = NULL; cil_list_for_each(i, cp->perms) { struct cil_perm *cmp = i->data; if (&cmp->datum == orig) { rc = SEPOL_ERR; goto exit; } rc = __cil_verify_classperms(cmp->classperms, orig); if (rc != SEPOL_OK) { goto exit; } } } } else { /* SET */ struct cil_classperms_set *cp_set = curr->data; struct cil_classpermission *cp = cp_set->set; if (&cp->datum == orig) { rc = SEPOL_ERR; goto exit; } rc = __cil_verify_classperms(cp->classperms, orig); if (rc != SEPOL_OK) { goto exit; } } } return SEPOL_OK; exit: return rc; } static int __cil_verify_classpermission(struct cil_tree_node *node) { int rc = SEPOL_ERR; struct cil_classpermission *cp = node->data; rc = __cil_verify_classperms(cp->classperms, &cp->datum); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Found circular class permissions involving the set %s at line %d of %s\n",cp->datum.name, node->line, node->path); return rc; } return SEPOL_OK; } 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) { int rc = SEPOL_ERR; struct cil_verify_map_args *map_args = args; struct cil_perm *cmp = (struct cil_perm *)d; rc = __cil_verify_classperms(cmp->classperms, &cmp->datum); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Found circular class permissions involving the map class %s and permission %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path); map_args->rc = SEPOL_ERR; } 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; } static int __cil_verify_no_classperms_loop_helper(struct cil_tree_node *node, uint32_t *finished, __attribute__((unused)) void *extra_args) { int rc = SEPOL_ERR; if (node->flavor == CIL_OPTIONAL) { int state = ((struct cil_symtab_datum *)node->data)->state; if (state == CIL_STATE_DISABLED) { *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_BLOCK) { struct cil_block *blk = node->data; if (blk->is_abstract == CIL_TRUE) { *finished = CIL_TREE_SKIP_HEAD; } rc = SEPOL_OK; goto exit; } switch (node->flavor) { case CIL_MAP_CLASS: rc = __cil_verify_map_class(node); break; case CIL_CLASSPERMISSION: rc = __cil_verify_classpermission(node); break; default: rc = SEPOL_OK; break; } exit: return rc; } int cil_verify_no_classperms_loop(struct cil_db *db) { int rc = SEPOL_ERR; rc = cil_tree_walk(db->ast->root, __cil_verify_no_classperms_loop_helper, NULL, NULL, NULL); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to verify no loops in class permissions\n"); goto exit; } exit: return rc; } libsepol-2.4/cil/src/cil_verify.h000066400000000000000000000062601246370572200170460ustar00rootroot00000000000000/* * 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 char *name); int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], int 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_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list); 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_verify_no_classperms_loop(struct cil_db *db); #endif libsepol-2.4/cil/test/000077500000000000000000000000001246370572200147265ustar00rootroot00000000000000libsepol-2.4/cil/test/integration.cil000066400000000000000000000131411246370572200177420ustar00rootroot00000000000000(type bin_t) (type kernel_t) (type security_t) (type unlabeled_t) (policycap open_perms) (sensitivity s0) (sensitivity s1) (sensitivityalias s0 sens0) (dominance (s0 s1)) (category c0) (category c1) (category c2) (categoryalias c0 cat0) (categoryset cats01 (c0 c1)) (categoryorder (c0 c1 c2)) (categoryrange catrng02 (c0 c2)) (sensitivitycategory s0 (catrng02)) (sensitivitycategory s1 cats01) (sensitivitycategory s1 (c2)) (level low (s0 (c0))) (level high (s1 (c0 c1))) (levelrange low_high (low high)) (permissionset file_perms (execute_no_trans entrypoint execmod open audit_access)) (class file (execute_no_trans entrypoint execmod open audit_access)) (class process (open)) (common file (ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton)) (classcommon file file) (classpermissionset file_rw (file (read write getattr setattr lock append))) (class char (foo transition)) (classcommon char file) (classpermissionset char_w (char (write setattr))) (classmap files (read)) (classmapping files read (file (open read getattr)) char_w) (type auditadm_t) (type console_t) (type console_device_t) (type user_tty_device_t) (type device_t) (type getty_t) (type exec_t) (allow console_t console_device_t file_rw) (allow console_t console_device_t (files (read))) (boolean secure_mode false) (boolean console_login true) (sid kernel) (sid security) (sid unlabeled) (typeattribute exec_type) (typeattribute foo_type) (typeattribute bar_type) (typeattribute baz_type) (typeattributeset exec_type (or bin_t kernel_t)) (typeattributeset foo_type (and exec_type kernel_t)) (typeattributeset bar_type (xor exec_type foo_type)) (typeattributeset baz_type (not bin_t)) (typealias bin_t sbin_t) (typepermissive device_t) (typebounds device_t bin_t) (typemember device_t bin_t file exec_t) (typetransition device_t console_t file console_device_t) (rangetransition device_t console_t file low_high) (nametypetransition some_file device_t console_t file getty_t) (allow foo_type self (file (execute))) (allow bin_t device_t (file (execute))) (booleanif secure_mode (true (auditallow device_t exec_t (file (read write))) ) ) (booleanif console_login (true (typechange auditadm_t console_device_t file user_tty_device_t) (allow getty_t console_device_t (file (getattr open read write append))) ) (false (dontaudit getty_t console_device_t (file (getattr open read write append))) ) ) (booleanif (not (xor (eq secure_mode console_login) (and (or secure_mode console_login) secure_mode ) ) ) (true (allow bin_t exec_t (file (execute))) ) ) (tunable allow_execfile true) (tunable allow_userexec false) (tunableif (not (xor (eq allow_execfile allow_userexec) (and (or allow_execfile allow_userexec) (and allow_execfile allow_userexec) ) ) ) (true (allow bin_t exec_t (file (execute))) ) ) (optional allow_rules (allow user_t exec_t (bins (execute))) ) (dontaudit device_t auditadm_t (file (read))) (auditallow device_t auditadm_t (file (open))) (user system_u) (user user_u) (userprefix user_u user) (userprefix system_u user) (selinuxuser name user_u low_high) (selinuxuserdefault user_u low_high) (role system_r) (role user_r) (roletype system_r bin_t) (roletype system_r kernel_t) (roletype system_r security_t) (roletype system_r unlabeled_t) (roleallow system_r user_r) (rolebounds system_r user_r) (roletransition system_r bin_t process user_r) (userrole system_u system_r) (userlevel system_u low) (userrange system_u low_high) (userbounds system_u user_u) (userrole user_u user_r) (userlevel user_u low) (userrange user_u (low low)) (sidcontext kernel (system_u system_r kernel_t (low high))) (sidcontext security (system_u system_r security_t (low high))) (sidcontext unlabeled (system_u system_r unlabeled_t (low high))) (context system_u_bin_t_l2h (system_u system_r bin_t (low high))) (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::) (filecon "/usr/bin/" "foo" file system_u_bin_t_l2h) (filecon "/usr/bin/" "bar" file ()) (filecon "/usr/bin/" "baz" any ()) (nodecon ip_v4 netmask system_u_bin_t_l2h) (nodecon ip_v6 netmask_v6 system_u_bin_t_l2h) (portcon udp 25 system_u_bin_t_l2h) (portcon tcp 22 system_u_bin_t_l2h) (genfscon - "/usr/bin" system_u_bin_t_l2h) (netifcon eth0 system_u_bin_t_l2h system_u_bin_t_l2h) ;different contexts? (fsuse xattr ext3 system_u_bin_t_l2h) ; XEN (pirqcon 256 system_u_bin_t_l2h) (iomemcon (0 255) system_u_bin_t_l2h) (ioportcon (22 22) system_u_bin_t_l2h) (pcidevicecon 345 system_u_bin_t_l2h) (constrain (files (read)) (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2)))) (constrain char_w (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2)))) (constrain (file (read)) (or (and (eq t1 exec_t) (neq t2 bin_t) ) (eq u1 u2) ) ) (constrain (file (open)) (dom r1 r2)) (constrain (file (open)) (domby r1 r2)) (constrain (file (open)) (incomp r1 r2)) (validatetrans file (eq t1 exec_t)) (mlsconstrain (file (open)) (not (or (and (eq l1 l2) (eq u1 u2)) (eq r1 r2)))) (mlsconstrain (file (open)) (or (and (eq l1 l2) (eq u1 u2)) (neq r1 r2))) (mlsconstrain (file (open)) (dom h1 l2)) (mlsconstrain (file (open)) (domby l1 h2)) (mlsconstrain (file (open)) (incomp l1 l2)) (mlsvalidatetrans file (domby l1 h2)) (macro all ((type x)) (allow x bin_t (file (execute))) ) (call all (bin_t)) (type a_t) (type b_t) (boolean b1 false) (tunable tun1 true) (macro m ((boolean b)) (tunableif tun1 (true (allow a_t b_t (file (write)))) (false (allow a_t b_t (file (execute))))) (booleanif b (true (allow a_t b_t (file (read)))))) (call m (b1)) libsepol-2.4/cil/test/integration_testing/000077500000000000000000000000001246370572200210065ustar00rootroot00000000000000libsepol-2.4/cil/test/integration_testing/mls_policy.cil000066400000000000000000000047111246370572200236540ustar00rootroot00000000000000(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))) libsepol-2.4/cil/test/integration_testing/nonmls.cil000066400000000000000000000032761246370572200230150ustar00rootroot00000000000000(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))) libsepol-2.4/cil/test/integration_testing/nonmls.conf000066400000000000000000000013701246370572200231640ustar00rootroot00000000000000 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 libsepol-2.4/cil/test/integration_testing/ordered_lists_bad1.cil000066400000000000000000000013051246370572200252270ustar00rootroot00000000000000; 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)) libsepol-2.4/cil/test/integration_testing/ordered_lists_bad2.cil000066400000000000000000000013021246370572200252250ustar00rootroot00000000000000; 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)) libsepol-2.4/cil/test/integration_testing/ordered_lists_bad3.cil000066400000000000000000000013261246370572200252340ustar00rootroot00000000000000; 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)) libsepol-2.4/cil/test/integration_testing/ordered_lists_easy.cil000066400000000000000000000011461246370572200253640ustar00rootroot00000000000000; 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)) libsepol-2.4/cil/test/integration_testing/ordered_lists_hard.cil000066400000000000000000000013311246370572200253350ustar00rootroot00000000000000; 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)) libsepol-2.4/cil/test/integration_testing/small.cil000066400000000000000000000000761246370572200226120ustar00rootroot00000000000000(class foo (read)) (type bar) (allow bar self (foo (read))) libsepol-2.4/cil/test/policy.cil000066400000000000000000000213501246370572200167170ustar00rootroot00000000000000(type bin_t) (type kernel_t) (type security_t) (type unlabeled_t) (handleunknown allow) (mls true) (policycap open_perms) (category c0) (category c1) (category c2) (category c3) (category c4) (category c5) (categoryalias cat0) (categoryaliasactual cat0 c0) (categoryset cats01 (c0 c1)) (categoryset cats02 (c2 c3)) (categoryset cats03 (range c0 c5)) (categoryset cats04 (not (range c0 c2))) (categoryorder (cat0 c1 c2 c3)) (categoryorder (c3 c4 c5)) (sensitivity s0) (sensitivity s1) (sensitivity s2) (sensitivity s3) (sensitivityalias sens0) (sensitivityaliasactual sens0 s0) (sensitivityorder (s0 s1 s2 s3)) (sensitivitycategory s0 (cats03)) (sensitivitycategory s1 cats01) (sensitivitycategory s1 (c2)) (sensitivitycategory s2 (cats01 cats02)) (sensitivitycategory s2 (range c4 c5)) (sensitivitycategory s3 (range c0 c5)) (level low (s0)) (level high (s3 (range c0 c3))) (levelrange low_high (low high)) (levelrange lh1 ((s0 (c0)) (s2 (c0 c3)))) (levelrange lh2 (low (s2 (c0 c3)))) (levelrange lh3 ((s0 cats04) (s2 (range c0 c5)))) (levelrange lh4 ((s0) (s1))) (block policy (classorder (file char dir)) (class file (execute_no_trans entrypoint execmod open audit_access)) (common file (ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton)) (classcommon file file) (classpermission file_rw) (classpermissionset file_rw (file (read write getattr setattr lock append))) ;;(classpermission loop1) ;;(classpermissionset loop1 ((loop2))) ;;(classpermission loop2) ;;(classpermissionset loop2 ((loop3))) ;;(classpermission loop3) ;;(classpermissionset loop3 ((loop1))) (class char (foo)) (classcommon char file) (class dir ()) (classcommon dir file) (classpermission char_w) (classpermissionset char_w (char (write setattr))) (classpermissionset char_w (file (open read getattr))) (classmap files (read)) (classmapping files read (file (open read getattr))) (classmapping files read char_w) (type auditadm_t) (type console_t) (type console_device_t) (type user_tty_device_t) (type device_t) (type getty_t) (type exec_t) (type bad_t) ;;(allow console_t console_device_t file_rw) (allow console_t console_device_t (files (read))) (boolean secure_mode false) (boolean console_login true) (sid kernel) (sid security) (sid unlabeled) (sidorder (kernel security)) (sidorder (security unlabeled)) (typeattribute exec_type) (typeattribute foo_type) (typeattribute bar_type) (typeattribute baz_type) (typeattribute not_bad_type) (typeattributeset exec_type (or bin_t kernel_t)) (typeattributeset foo_type (and exec_type kernel_t)) (typeattributeset bar_type (xor exec_type foo_type)) (typeattributeset baz_type (not bin_t)) (typeattributeset baz_type (and exec_type (and bar_type bin_t))) (typeattributeset not_bad_type (not bad_t)) (typealias sbin_t) (typealiasactual sbin_t bin_t) (typepermissive device_t) (typebounds device_t bin_t) ;;(typebounds bin_t kernel_t) ;; This statement and the next can be used ;;(typebounds kernel_t device_t) ;; to verify that circular bounds can be found (typemember device_t bin_t file exec_t) (typetransition device_t console_t files console_device_t) (roleattribute exec_role) (roleattribute foo_role) (roleattribute bar_role) (roleattribute baz_role) (roleattributeset exec_role (or user_r system_r)) (roleattributeset foo_role (and exec_role system_r)) (roleattributeset bar_role (xor exec_role foo_role)) (roleattributeset baz_role (not user_r)) (rangetransition device_t console_t file low_high) (rangetransition device_t kernel_t file ((s0) (s3 (not c3)))) (typetransition device_t console_t file "some_file" getty_t) (allow foo_type self (file (execute))) (allow bin_t device_t (file (execute))) ;; Next two rules violate the neverallow rule that follows ;;(allow bad_t not_bad_type (file (execute))) ;;(allow bad_t exec_t (file (execute))) (neverallow bad_t not_bad_type (file (execute))) (booleanif secure_mode (true (auditallow device_t exec_t (file (read write))) ) ) (booleanif console_login (true (typechange auditadm_t console_device_t file user_tty_device_t) (allow getty_t console_device_t (file (getattr open read write append))) ) (false (dontaudit getty_t console_device_t (file (getattr open read write append))) ) ) (booleanif (not (xor (eq secure_mode console_login) (and (or secure_mode console_login) secure_mode ) ) ) (true (allow bin_t exec_t (file (execute))) ) ) (tunable allow_execfile true) (tunable allow_userexec false) (tunableif (not (xor (eq allow_execfile allow_userexec) (and (or allow_execfile allow_userexec) (and allow_execfile allow_userexec) ) ) ) (true (allow bin_t exec_t (file (execute))) ) ) (optional allow_rules (allow user_t exec_t (bins (execute))) ) (dontaudit device_t auditadm_t (file (read))) (auditallow device_t auditadm_t (file (open))) (user system_u) (user user_u) (user foo_u) (userprefix user_u user) (userprefix system_u user) (selinuxuser name user_u low_high) (selinuxuserdefault user_u ((s0 (c0)) (s3 (range c0 c3)))) (role system_r) (role user_r) (roletype system_r bin_t) (roletype system_r kernel_t) (roletype system_r security_t) (roletype system_r unlabeled_t) (roletype system_r exec_type) (roletype exec_role bin_t) (roletype exec_role exec_type) (roleallow system_r user_r) (rolebounds system_r user_r) (roletransition system_r bin_t file user_r) (userrole foo_u foo_role) (userlevel foo_u low) (userrange foo_u low_high) (userrole system_u system_r) (userlevel system_u low) (userrange system_u low_high) (userbounds system_u user_u) (userrole user_u user_r) (userlevel user_u (s0 (range c0 c2))) (userrange user_u (low high)) (sidcontext kernel (system_u system_r kernel_t ((s0) high))) (sidcontext security (system_u system_r security_t (low (s3 (range c0 c3))))) (sidcontext unlabeled (system_u system_r unlabeled_t (low high))) (context system_u_bin_t_l2h (system_u system_r bin_t (low high))) (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::) (filecon "/usr/bin/foo" file system_u_bin_t_l2h) (filecon "/usr/bin/bar" file (system_u system_r kernel_t (low low))) (filecon "/usr/bin/baz" any ()) (filecon "/usr/bin/aaa" any (system_u system_r kernel_t ((s0) (s3 (range c0 c2))))) (filecon "/usr/bin/bbb" any (system_u system_r kernel_t ((s0 (c0)) high))) (filecon "/usr/bin/ccc" any (system_u system_r kernel_t (low (s3 (cats01))))) (filecon "/usr/bin/ddd" any (system_u system_r kernel_t (low (s3 (cats01 cats02))))) (nodecon ip_v4 netmask system_u_bin_t_l2h) (nodecon ip_v6 netmask_v6 system_u_bin_t_l2h) (portcon udp 25 system_u_bin_t_l2h) (portcon tcp 22 system_u_bin_t_l2h) (genfscon - "/usr/bin" system_u_bin_t_l2h) (netifcon eth0 system_u_bin_t_l2h system_u_bin_t_l2h) ;different contexts? (fsuse xattr ext3 system_u_bin_t_l2h) ; XEN (pirqcon 256 system_u_bin_t_l2h) (iomemcon (0 255) system_u_bin_t_l2h) (ioportcon (22 22) system_u_bin_t_l2h) (pcidevicecon 345 system_u_bin_t_l2h) (constrain (files (read)) (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2)))) (constrain char_w (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2)))) (constrain (file (read)) (or (and (eq t1 exec_t) (neq t2 bin_t) ) (eq u1 u2) ) ) (constrain (file (open)) (dom r1 r2)) (constrain (file (open)) (domby r1 r2)) (constrain (file (open)) (incomp r1 r2)) (validatetrans file (eq t1 exec_t)) (mlsconstrain (file (open)) (not (or (and (eq l1 l2) (eq u1 u2)) (eq r1 r2)))) (mlsconstrain (file (open)) (or (and (eq l1 l2) (eq u1 u2)) (neq r1 r2))) (mlsconstrain (file (open)) (dom h1 l2)) (mlsconstrain (file (open)) (domby l1 h2)) (mlsconstrain (file (open)) (incomp l1 l2)) (mlsvalidatetrans file (domby l1 h2)) (macro test_mapping ((classpermission cps)) (allow bin_t auditadm_t cps)) (call test_mapping ((file (read)))) (call test_mapping ((files (read)))) (call test_mapping (char_w)) (defaultuser (file char) source) (defaultrole char target) (defaulttype (files) source) (defaultrange (file) target low) (defaultrange (char) source low-high) ) (macro all ((type x)) (allow x bin_t (policy.file (execute))) ) (call all (bin_t)) (block z (block ba (roletype r t) (blockabstract z.ba))) (block test_ba (blockinherit z.ba) (role r) (type t)) (block bb (type t1) (type t2) (boolean b1 false) (tunable tun1 true) (macro m ((boolean b)) (tunableif tun1 (true (allow t1 t2 (policy.file (write)))) (false (allow t1 t2 (policy.file (execute))))) (booleanif b (true (allow t1 t2 (policy.file (read)))))) (call m (b1)) ) (in bb (tunableif bb.tun1 (true (allow bb.t2 bb.t1 (policy.file (read write execute)))))) libsepol-2.4/cil/test/policy.conf000066400000000000000000000077601246370572200171060ustar00rootroot00000000000000class file class process class char sid kernel sid security sid unlabeled common file {ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton } class file inherits file { execute_no_trans entrypoint execmod open audit_access } class char inherits file { foo transition } class process { open } sensitivity s0 alias sens0; sensitivity s1; dominance { s0 s1 } category c0 alias cat0; category c1; category c2; level s0:c0.c2; level s1:c0.c2; mlsconstrain file { open } (not (((l1 eq l2) and (u1 eq u2)) or (r1 eq r2))); mlsconstrain file { open } (((l1 eq l2) and (u1 eq u2)) or (r1 != r2)); mlsconstrain file { open } (l1 dom h2); mlsconstrain file { open } (h1 domby l2); mlsconstrain file { open } (l1 incomp l2); mlsvalidatetrans file (h1 domby l2); attribute foo_type; attribute bar_type; attribute baz_type; attribute exec_type; type bin_t, bar_type, exec_type; type kernel_t, foo_type, exec_type, baz_type; type security_t, baz_type; type unlabeled_t, baz_type; type exec_t, baz_type; type console_t, baz_type; type auditadm_t, baz_type; type console_device_t, baz_type; type user_tty_device_t, baz_type; type device_t, baz_type; type getty_t, baz_type; type a_t, baz_type; type b_t, baz_type; typealias bin_t alias sbin_t; bool secure_mode false; bool console_login true; bool b1 false; role system_r; role user_r; role system_r types bin_t; role system_r types kernel_t; role system_r types security_t; role system_r types unlabeled_t; policycap open_perms; permissive device_t; range_transition device_t console_t : file s0:c0 - s1:c0.c1; type_transition device_t console_t : file console_device_t; type_member device_t bin_t : file exec_t; if console_login{ type_change auditadm_t console_device_t : file user_tty_device_t; } role_transition system_r bin_t user_r; auditallow device_t auditadm_t: file { open }; dontaudit device_t auditadm_t: file { read }; allow system_r user_r; allow console_t console_device_t: char { write setattr }; allow console_t console_device_t: file { open read getattr }; allow foo_type self: file { execute }; allow bin_t device_t: file { execute }; allow bin_t exec_t: file { execute }; allow bin_t bin_t: file { execute }; allow a_t b_t : file { write }; allow console_t console_device_t: file { read write getattr setattr lock append }; allow kernel_t kernel_t : file { execute }; if b1 { allow a_t b_t : file { read }; } if secure_mode{ auditallow device_t exec_t: file { read write }; } if console_login{ allow getty_t console_device_t: file { getattr open read write append }; } else { dontaudit getty_t console_device_t: file { getattr open read write append }; } if (not ((secure_mode eq console_login) xor ((secure_mode or console_login) and secure_mode))){ allow bin_t exec_t: file { execute }; } user system_u roles system_r level s0:c0 range s0:c0 - s1:c0,c1; user user_u roles user_r level s0:c0 range s0:c0 - s0:c0; validatetrans file (t1 == exec_t); constrain char transition (not (((t1 eq exec_t) and (t2 eq bin_t)) or (r1 eq r2))); constrain file { open } (r1 dom r2); constrain file { open } (r1 domby r2); constrain file { open } (r1 incomp r2); constrain file { open read getattr } (not (((t1 eq exec_t) and (t2 eq bin_t)) or (r1 eq r2))); constrain char { write setattr } (not (((t1 eq exec_t) and (t2 eq bin_t)) or (r1 eq r2))); sid kernel system_u:system_r:kernel_t:s0:c0 - s1:c0,c1 sid security system_u:system_r:security_t:s0:c0 - s1:c0,c1 sid unlabeled system_u:system_r:unlabeled_t:s0:c0 - s1:c0,c1 fs_use_xattr ext3 system_u:system_r:bin_t:s0:c0 - s1:c0,c1; genfscon proc /usr/bin system_u:system_r:bin_t:s0:c0 - s1:c0,c1 portcon tcp 22 system_u:system_r:bin_t:s0:c0 - s1:c0,c1 portcon udp 25 system_u:system_r:bin_t:s0:c0 - s1:c0,c1 netifcon eth0 system_u:system_r:bin_t:s0:c0 - s1:c0,c1 system_u:system_r:bin_t:s0:c0 - s1:c0,c1 nodecon 192.25.35.200 192.168.1.1 system_u:system_r:bin_t:s0:c0 - s1:c0,c1 nodecon 2001:db8:ac10:fe01:: 2001:de0:da88:2222:: system_u:system_r:bin_t:s0:c0 - s1:c0,c1 libsepol-2.4/cil/test/unit/000077500000000000000000000000001246370572200157055ustar00rootroot00000000000000libsepol-2.4/cil/test/unit/AllTests.c000066400000000000000000000055731246370572200176160ustar00rootroot00000000000000/* * 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; } libsepol-2.4/cil/test/unit/CilTest.c000066400000000000000000003150531246370572200174270ustar00rootroot00000000000000/* * 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 = 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 = 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; } libsepol-2.4/cil/test/unit/CilTest.h000066400000000000000000000035501246370572200174300ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/CuTest.c000066400000000000000000000215131246370572200172620ustar00rootroot00000000000000/* * 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); } } libsepol-2.4/cil/test/unit/CuTest.h000066400000000000000000000116141246370572200172700ustar00rootroot00000000000000/* * 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 */ libsepol-2.4/cil/test/unit/test_cil.c000066400000000000000000000125311246370572200176610ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil.h000066400000000000000000000041301246370572200176620ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_build_ast.c000066400000000000000000021564561246370572200217300ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_build_ast.h000066400000000000000000001562351246370572200217260ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_copy_ast.c000066400000000000000000002323711246370572200215700ustar00rootroot00000000000000/* * 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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); } libsepol-2.4/cil/test/unit/test_cil_copy_ast.h000066400000000000000000000147131246370572200215730ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_fqn.c000066400000000000000000000055201246370572200205250ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_fqn.h000066400000000000000000000033621246370572200205340ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_lexer.c000066400000000000000000000067321246370572200210660ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_lexer.h000066400000000000000000000033471246370572200210720ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_list.c000066400000000000000000000256071246370572200207240ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_list.h000066400000000000000000000042361246370572200207240ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_parser.c000066400000000000000000000043601246370572200212360ustar00rootroot00000000000000/* * 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 } libsepol-2.4/cil/test/unit/test_cil_parser.h000066400000000000000000000033001246370572200212340ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_post.c000066400000000000000000000506661246370572200207410ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_post.h000066400000000000000000000101701246370572200207300ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_resolve_ast.c000066400000000000000000014225521246370572200223000ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_resolve_ast.h000066400000000000000000000640471246370572200223050ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_symtab.c000066400000000000000000000047271246370572200212500ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_symtab.h000066400000000000000000000033071246370572200212460ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_cil_tree.c000066400000000000000000000054211246370572200207000ustar00rootroot00000000000000/* * 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); } libsepol-2.4/cil/test/unit/test_cil_tree.h000066400000000000000000000033471246370572200207120ustar00rootroot00000000000000/* * 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 libsepol-2.4/cil/test/unit/test_integration.c000066400000000000000000000061731246370572200214420ustar00rootroot00000000000000/* * 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)); } libsepol-2.4/cil/test/unit/test_integration.h000066400000000000000000000033411246370572200214410ustar00rootroot00000000000000/* * 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 libsepol-2.4/include/000077500000000000000000000000001246370572200146235ustar00rootroot00000000000000libsepol-2.4/include/Makefile000066400000000000000000000010301246370572200162550ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr INCDIR ?= $(PREFIX)/include/sepol CILDIR ?= ../cil all: install: all test -d $(INCDIR) || install -m 755 -d $(INCDIR) test -d $(INCDIR)/policydb || install -m 755 -d $(INCDIR)/policydb test -d $(INCDIR)/cil || install -m 755 -d $(INCDIR)/cil install -m 644 $(wildcard sepol/*.h) $(INCDIR) install -m 644 $(wildcard sepol/policydb/*.h) $(INCDIR)/policydb install -m 644 $(wildcard $(CILDIR)/include/cil/*.h) $(INCDIR)/cil indent: ../../scripts/Lindent $(wildcard sepol/*.h) libsepol-2.4/include/sepol/000077500000000000000000000000001246370572200157455ustar00rootroot00000000000000libsepol-2.4/include/sepol/boolean_record.h000066400000000000000000000027741246370572200211050ustar00rootroot00000000000000#ifndef _SEPOL_BOOLEAN_RECORD_H_ #define _SEPOL_BOOLEAN_RECORD_H_ #include #include #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/booleans.h000066400000000000000000000042531246370572200177240ustar00rootroot00000000000000#ifndef _SEPOL_BOOLEANS_H_ #define _SEPOL_BOOLEANS_H_ #include #include #include #include #include __BEGIN_DECLS /*--------------compatibility--------------*/ /* Given an existing binary policy (starting at 'data', with length 'len') and a boolean configuration file named by 'boolpath', rewrite the binary policy for the boolean settings in the boolean configuration file. The binary policy is rewritten in place in memory. Returns 0 upon success, or -1 otherwise. */ extern int sepol_genbools(void *data, size_t len, char *boolpath); /* Given an existing binary policy (starting at 'data', with length 'len') and boolean settings specified by the parallel arrays ('names', 'values') with 'nel' elements, rewrite the binary policy for the boolean settings. The binary policy is rewritten in place in memory. Returns 0 upon success or -1 otherwise. */ extern int sepol_genbools_array(void *data, size_t len, char **names, int *values, int nel); /*---------------end compatbility------------*/ /* 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); __END_DECLS #endif libsepol-2.4/include/sepol/context.h000066400000000000000000000013351246370572200176040ustar00rootroot00000000000000#ifndef _SEPOL_CONTEXT_H_ #define _SEPOL_CONTEXT_H_ #include #include #include #include __BEGIN_DECLS /* -- 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); __END_DECLS #endif libsepol-2.4/include/sepol/context_record.h000066400000000000000000000031631246370572200211430ustar00rootroot00000000000000#ifndef _SEPOL_CONTEXT_RECORD_H_ #define _SEPOL_CONTEXT_RECORD_H_ #include #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/debug.h000066400000000000000000000016741246370572200172140ustar00rootroot00000000000000#ifndef _SEPOL_DEBUG_H_ #define _SEPOL_DEBUG_H_ #include #include __BEGIN_DECLS /* 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); __END_DECLS #endif libsepol-2.4/include/sepol/errcodes.h000066400000000000000000000015011246370572200177210ustar00rootroot00000000000000/* Author: Karl MacMillan */ #ifndef __sepol_errno_h__ #define __sepol_errno_h__ #include #include __BEGIN_DECLS #define SEPOL_OK 0 /* These first error codes are defined for compatibility with * previous version of libsepol. In the future, custome 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 __END_DECLS #endif libsepol-2.4/include/sepol/handle.h000066400000000000000000000025371246370572200173600ustar00rootroot00000000000000#ifndef _SEPOL_HANDLE_H_ #define _SEPOL_HANDLE_H_ #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/iface_record.h000066400000000000000000000034351246370572200205300ustar00rootroot00000000000000#ifndef _SEPOL_IFACE_RECORD_H_ #define _SEPOL_IFACE_RECORD_H_ #include #include #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/interfaces.h000066400000000000000000000025501246370572200202430ustar00rootroot00000000000000#ifndef __SEPOL_INTERFACES_H_ #define __SEPOL_INTERFACES_H_ #include #include #include #include __BEGIN_DECLS /* 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); __END_DECLS #endif libsepol-2.4/include/sepol/module.h000066400000000000000000000051451246370572200174100ustar00rootroot00000000000000#ifndef _SEPOL_MODULE_H_ #define _SEPOL_MODULE_H_ #include #include #include #include #include #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/node_record.h000066400000000000000000000053431246370572200204060ustar00rootroot00000000000000#ifndef _SEPOL_NODE_RECORD_H_ #define _SEPOL_NODE_RECORD_H_ #include #include #include #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/nodes.h000066400000000000000000000024151246370572200172300ustar00rootroot00000000000000#ifndef _SEPOL_NODES_H_ #define _SEPOL_NODES_H_ #include #include #include #include __BEGIN_DECLS /* 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); __END_DECLS #endif libsepol-2.4/include/sepol/policydb.h000066400000000000000000000111041246370572200177200ustar00rootroot00000000000000#ifndef _SEPOL_POLICYDB_H_ #define _SEPOL_POLICYDB_H_ #include #include #include #include __BEGIN_DECLS 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); /* * 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); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/000077500000000000000000000000001246370572200175525ustar00rootroot00000000000000libsepol-2.4/include/sepol/policydb/avrule_block.h000066400000000000000000000031221246370572200223710ustar00rootroot00000000000000/* 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 #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/avtab.h000066400000000000000000000101421246370572200210160ustar00rootroot00000000000000 /* 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 __BEGIN_DECLS typedef struct avtab_key { uint16_t source_type; uint16_t target_type; uint16_t target_class; #define AVTAB_ALLOWED 1 #define AVTAB_AUDITALLOW 2 #define AVTAB_AUDITDENY 4 #define AVTAB_NEVERALLOW 128 #define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) #define AVTAB_TRANSITION 16 #define AVTAB_MEMBER 32 #define AVTAB_CHANGE 64 #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) #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_datum { uint32_t data; /* access vector or type */ } 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 avtab_init(avtab_t *); extern int 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 *avtab_search(avtab_t * h, avtab_key_t * k); extern void 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 avtab_hash_eval(avtab_t * h, char *tag); struct policy_file; extern int 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 avtab_read(avtab_t * a, struct policy_file *fp, uint32_t vers); extern avtab_ptr_t 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 avtab_search_node(avtab_t * h, avtab_key_t * key); extern avtab_ptr_t 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) __END_DECLS #endif /* _AVTAB_H_ */ /* FLASK */ libsepol-2.4/include/sepol/policydb/conditional.h000066400000000000000000000111521246370572200222260ustar00rootroot00000000000000/* 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 #include __BEGIN_DECLS #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 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 cond_policydb_init(policydb_t * p); extern void cond_policydb_destroy(policydb_t * p); extern void cond_list_destroy(cond_list_t * list); extern int cond_init_bool_indexes(policydb_t * p); extern int cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p); extern int cond_index_bool(hashtab_key_t key, hashtab_datum_t datum, void *datap); extern int cond_read_bool(policydb_t * p, hashtab_t h, struct policy_file *fp); extern int cond_read_list(policydb_t * p, cond_list_t ** list, void *fp); extern void cond_compute_av(avtab_t * ctab, avtab_key_t * key, struct sepol_av_decision *avd); __END_DECLS #endif /* _CONDITIONAL_H_ */ libsepol-2.4/include/sepol/policydb/constraint.h000066400000000000000000000047421246370572200221160ustar00rootroot00000000000000/* 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 __BEGIN_DECLS #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); __END_DECLS #endif /* _CONSTRAINT_H_ */ /* FLASK */ libsepol-2.4/include/sepol/policydb/context.h000066400000000000000000000043051246370572200214110ustar00rootroot00000000000000/* 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 __BEGIN_DECLS /* * 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, context_struct_t * src) { if (mls_range_cpy(&dst->range, &src->range) < 0) return -1; return 0; } static inline int mls_context_cmp(context_struct_t * c1, 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, 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(context_struct_t * c1, context_struct_t * c2) { return ((c1->user == c2->user) && (c1->role == c2->role) && (c1->type == c2->type) && mls_context_cmp(c1, c2)); } __END_DECLS #endif libsepol-2.4/include/sepol/policydb/ebitmap.h000066400000000000000000000060161246370572200213470ustar00rootroot00000000000000/* 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 __BEGIN_DECLS #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_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(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)) \ extern int 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 ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2); extern int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2); extern int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit); extern int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit); extern unsigned int ebitmap_cardinality(ebitmap_t *e1); extern int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2); extern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src); extern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2); extern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit); extern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value); extern void ebitmap_destroy(ebitmap_t * e); extern int ebitmap_read(ebitmap_t * e, void *fp); __END_DECLS #endif /* _EBITMAP_H_ */ /* FLASK */ libsepol-2.4/include/sepol/policydb/expand.h000066400000000000000000000070651246370572200212120ustar00rootroot00000000000000/* 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 #include __BEGIN_DECLS /* * 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); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/flask.h000066400000000000000000000116001246370572200210210ustar00rootroot00000000000000/* This file is automatically generated. Do not edit. */ #ifndef _SEPOL_POLICYDB_FLASK_H_ #define _SEPOL_POLICYDB_FLASK_H_ /* * Security object class definitions */ #define SECCLASS_SECURITY 1 #define SECCLASS_PROCESS 2 #define SECCLASS_SYSTEM 3 #define SECCLASS_CAPABILITY 4 #define SECCLASS_FILESYSTEM 5 #define SECCLASS_FILE 6 #define SECCLASS_DIR 7 #define SECCLASS_FD 8 #define SECCLASS_LNK_FILE 9 #define SECCLASS_CHR_FILE 10 #define SECCLASS_BLK_FILE 11 #define SECCLASS_SOCK_FILE 12 #define SECCLASS_FIFO_FILE 13 #define SECCLASS_SOCKET 14 #define SECCLASS_TCP_SOCKET 15 #define SECCLASS_UDP_SOCKET 16 #define SECCLASS_RAWIP_SOCKET 17 #define SECCLASS_NODE 18 #define SECCLASS_NETIF 19 #define SECCLASS_NETLINK_SOCKET 20 #define SECCLASS_PACKET_SOCKET 21 #define SECCLASS_KEY_SOCKET 22 #define SECCLASS_UNIX_STREAM_SOCKET 23 #define SECCLASS_UNIX_DGRAM_SOCKET 24 #define SECCLASS_SEM 25 #define SECCLASS_MSG 26 #define SECCLASS_MSGQ 27 #define SECCLASS_SHM 28 #define SECCLASS_IPC 29 #define SECCLASS_PASSWD 30 #define SECCLASS_DRAWABLE 31 #define SECCLASS_WINDOW 32 #define SECCLASS_GC 33 #define SECCLASS_FONT 34 #define SECCLASS_COLORMAP 35 #define SECCLASS_PROPERTY 36 #define SECCLASS_CURSOR 37 #define SECCLASS_XCLIENT 38 #define SECCLASS_XINPUT 39 #define SECCLASS_XSERVER 40 #define SECCLASS_XEXTENSION 41 #define SECCLASS_PAX 42 #define SECCLASS_NETLINK_ROUTE_SOCKET 43 #define SECCLASS_NETLINK_FIREWALL_SOCKET 44 #define SECCLASS_NETLINK_TCPDIAG_SOCKET 45 #define SECCLASS_NETLINK_NFLOG_SOCKET 46 #define SECCLASS_NETLINK_XFRM_SOCKET 47 #define SECCLASS_NETLINK_SELINUX_SOCKET 48 #define SECCLASS_NETLINK_AUDIT_SOCKET 49 #define SECCLASS_NETLINK_IP6FW_SOCKET 50 #define SECCLASS_NETLINK_DNRT_SOCKET 51 #define SECCLASS_DBUS 52 /* * 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 libsepol-2.4/include/sepol/policydb/flask_types.h000066400000000000000000000033421246370572200222510ustar00rootroot00000000000000/* -*- 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 __BEGIN_DECLS /* * 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; /* * 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 flask/access_vectors, and the corresponding constants * for permissions are defined in the automatically generated * header file av_permissions.h. */ 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 flask/security_classes, * with the corresponding constants defined in the automatically * generated header file flask.h. */ 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; }; __END_DECLS #endif libsepol-2.4/include/sepol/policydb/hashtab.h000066400000000000000000000102731246370572200213400ustar00rootroot00000000000000/* 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 #include __BEGIN_DECLS typedef char *hashtab_key_t; /* 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, hashtab_key_t key); /* hash function */ int (*keycmp) (struct hashtab_val * h, hashtab_key_t key1, 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 insufficent 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); /* Insert or replace the specified (key, datum) pair in the specified hash table. If an entry for the specified key already exists, then the specified destroy function is applied to (key,datum,args) for the entry prior to replacing the entry's contents. Returns SEPOL_ENOMEM if insufficient space is available or SEPOL_OK otherwise. */ extern int hashtab_replace(hashtab_t h, hashtab_key_t k, hashtab_datum_t d, 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 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 hashtab_map will cease iterating through the hash table and will propagate the error return to its caller. */ extern int hashtab_map(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); /* Same as hashtab_map, except that if apply returns a non-zero status, then the (key,datum) pair will be removed from the hashtab and the destroy function will be applied to (key,datum,args). */ extern void hashtab_map_remove_on_error(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args); extern void hashtab_hash_eval(hashtab_t h, char *tag); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/hierarchy.h000066400000000000000000000024121246370572200217000ustar00rootroot00000000000000/* 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 __BEGIN_DECLS extern int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/link.h000066400000000000000000000007621246370572200206650ustar00rootroot00000000000000/* Authors: Jason Tang * Joshua Brindle * Karl MacMillan */ #ifndef _SEPOL_POLICYDB_LINK_H #define _SEPOL_POLICYDB_LINK_H #include #include #include #include #include __BEGIN_DECLS extern int link_modules(sepol_handle_t * handle, policydb_t * b, policydb_t ** mods, int len, int verbose); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/mls_types.h000066400000000000000000000104061246370572200217430ustar00rootroot00000000000000/* 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 #include #include __BEGIN_DECLS 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_level_cpy(struct mls_level *dst, struct mls_level *src) { dst->sens = src->sens; if (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; 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) && 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) && 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, 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(struct mls_range *r1, 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, 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, mls_semantic_range_t *src); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/module.h000066400000000000000000000027511246370572200212150ustar00rootroot00000000000000/* 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 #include #define SEPOL_MODULE_PACKAGE_MAGIC 0xf97cff8f __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/policydb/polcaps.h000066400000000000000000000012161246370572200213640ustar00rootroot00000000000000#ifndef _SEPOL_POLICYDB_POLCAPS_H_ #define _SEPOL_POLICYDB_POLCAPS_H_ #include __BEGIN_DECLS /* Policy capabilities */ enum { POLICYDB_CAPABILITY_NETPEER, POLICYDB_CAPABILITY_OPENPERM, POLICYDB_CAPABILITY_REDHAT1, /* reserved for RH testing of ptrace_child */ POLICYDB_CAPABILITY_ALWAYSNETWORK, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_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(int capnum); __END_DECLS #endif /* _SEPOL_POLICYDB_POLCAPS_H_ */ libsepol-2.4/include/sepol/policydb/policydb.h000066400000000000000000000570061246370572200215400ustar00rootroot00000000000000/* 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. * * 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 __BEGIN_DECLS /* * 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 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 { uint32_t stype; uint32_t ttype; uint32_t tclass; char *name; uint32_t otype; struct filename_trans *next; } filename_trans_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 0x01 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; mls_range_t target_range; struct range_trans *next; } 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; 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 1 #define AVRULE_AUDITALLOW 2 #define AVRULE_AUDITDENY 4 #define AVRULE_DONTAUDIT 8 #define AVRULE_NEVERALLOW 128 #define AVRULE_AV (AVRULE_ALLOWED | AVRULE_AUDITALLOW | AVRULE_AUDITDENY | AVRULE_DONTAUDIT | AVRULE_NEVERALLOW) #define AVRULE_TRANSITION 16 #define AVRULE_MEMBER 32 #define AVRULE_CHANGE 64 #define AVRULE_TYPE (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE) uint32_t specified; #define RULE_SELF 1 uint32_t flags; type_set_t stypes; type_set_t ttypes; class_perm_node_t *perms; 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 { 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 { uint32_t low_iomem; uint32_t high_iomem; } iomem; struct { uint32_t low_ioport; uint32_t high_ioport; } ioport; } 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_GENFS 7 /* needed for ocontext_supported */ /* 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 */ /* OCON_NUM needs to be the largest index in any platform's ocontext array */ #define OCON_NUM 7 /* 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; /* type transition rules with a 'name' component */ filename_trans_t *filename_trans; /* 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 */ range_trans_t *range_tr; 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; } 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_reindex_users(policydb_t * p); extern void policydb_destroy(policydb_t * p); extern int policydb_load_isids(policydb_t * p, sidtab_t * s); /* Deprecated */ extern int 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); typedef void (*hashtab_destroy_func_t) (hashtab_key_t k, hashtab_datum_t d, void *args); extern hashtab_destroy_func_t get_symtab_destroy_func(int sym_num); 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, type_set_t * src); extern int type_set_or_eq(type_set_t * dst, 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_assertions(sepol_handle_t * handle, policydb_t * p, avrule_t * avrules); extern int 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 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 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 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES /* 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_MIN MOD_POLICYDB_VERSION_BASE #define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_CONSTRAINT_NAMES #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" __END_DECLS #endif /* _POLICYDB_H_ */ /* FLASK */ libsepol-2.4/include/sepol/policydb/services.h000066400000000000000000000176711246370572200215620ustar00rootroot00000000000000 /* -*- linux-c -*- */ /* * Author : Stephen Smalley, */ #ifndef _SEPOL_POLICYDB_SERVICES_H_ #define _SEPOL_POLICYDB_SERVICES_H_ /* * Security server interface. */ #include #include #include #include __BEGIN_DECLS /* 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); /* Modify a policydb for boolean settings. */ int sepol_genbools_policydb(policydb_t * policydb, const char *booleans); /* Modify a policydb for user settings. */ int sepol_genusers_policydb(policydb_t * policydb, const char *usersdir); /* 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 1 #define SEPOL_COMPUTEAV_CONS 2 #define SEPOL_COMPUTEAV_RBAC 4 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 contraint * 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); /* * 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(const sepol_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 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 */ __END_DECLS #endif libsepol-2.4/include/sepol/policydb/sidtab.h000066400000000000000000000036461246370572200212020ustar00rootroot00000000000000/* 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 #include __BEGIN_DECLS 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); __END_DECLS #endif /* _SIDTAB_H_ */ /* FLASK */ libsepol-2.4/include/sepol/policydb/symtab.h000066400000000000000000000020741246370572200212250ustar00rootroot00000000000000 /* 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 #include __BEGIN_DECLS /* 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 symtab_init(symtab_t *, unsigned int size); extern void symtab_destroy(symtab_t *); __END_DECLS #endif /* _SYMTAB_H_ */ /* FLASK */ libsepol-2.4/include/sepol/policydb/util.h000066400000000000000000000023261246370572200207030ustar00rootroot00000000000000/* 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__ #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/port_record.h000066400000000000000000000036261246370572200204470ustar00rootroot00000000000000#ifndef _SEPOL_PORT_RECORD_H_ #define _SEPOL_PORT_RECORD_H_ #include #include #include __BEGIN_DECLS 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 /* 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); __END_DECLS #endif libsepol-2.4/include/sepol/ports.h000066400000000000000000000024151246370572200172670ustar00rootroot00000000000000#ifndef _SEPOL_PORTS_H_ #define _SEPOL_PORTS_H_ #include #include #include #include __BEGIN_DECLS /* 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); __END_DECLS #endif libsepol-2.4/include/sepol/roles.h000066400000000000000000000005011246370572200172360ustar00rootroot00000000000000#ifndef _SEPOL_ROLES_H_ #define _SEPOL_ROLES_H_ #include __BEGIN_DECLS extern int sepol_role_exists(const sepol_policydb_t * policydb, const char *role, int *response); extern int sepol_role_list(const sepol_policydb_t * policydb, char ***roles, unsigned int *nroles); __END_DECLS #endif libsepol-2.4/include/sepol/sepol.h000066400000000000000000000013151246370572200172400ustar00rootroot00000000000000#ifndef _SEPOL_H_ #define _SEPOL_H_ #include #include #include __BEGIN_DECLS #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); __END_DECLS #endif libsepol-2.4/include/sepol/user_record.h000066400000000000000000000044751246370572200204440ustar00rootroot00000000000000#ifndef _SEPOL_USER_RECORD_H_ #define _SEPOL_USER_RECORD_H_ #include #include #include __BEGIN_DECLS 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); __END_DECLS #endif libsepol-2.4/include/sepol/users.h000066400000000000000000000037241246370572200172650ustar00rootroot00000000000000#ifndef _SEPOL_USERS_H_ #define _SEPOL_USERS_H_ #include #include #include #include #include __BEGIN_DECLS /*---------compatibility------------*/ /* Given an existing binary policy (starting at 'data with length 'len') and user configurations living in 'usersdir', generate a new binary policy for the new user configurations. Sets '*newdata' and '*newlen' to refer to the new binary policy image. */ extern int sepol_genusers(void *data, size_t len, const char *usersdir, void **newdata, size_t * newlen); /* Enable or disable deletion of users by sepol_genusers(3) when a user in original binary policy image is not defined by the new user configurations. Defaults to disabled. */ extern void sepol_set_delusers(int on); /*--------end compatibility----------*/ /* 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); __END_DECLS #endif libsepol-2.4/man/000077500000000000000000000000001246370572200137535ustar00rootroot00000000000000libsepol-2.4/man/Makefile000066400000000000000000000003651246370572200154170ustar00rootroot00000000000000# Installation directories. MAN8DIR ?= $(DESTDIR)/usr/share/man/man8 MAN3DIR ?= $(DESTDIR)/usr/share/man/man3 all: install: all mkdir -p $(MAN3DIR) mkdir -p $(MAN8DIR) install -m 644 man3/*.3 $(MAN3DIR) install -m 644 man8/*.8 $(MAN8DIR) libsepol-2.4/man/man3/000077500000000000000000000000001246370572200146115ustar00rootroot00000000000000libsepol-2.4/man/man3/sepol_check_context.3000066400000000000000000000015411246370572200207210ustar00rootroot00000000000000.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. libsepol-2.4/man/man3/sepol_genbools.3000066400000000000000000000024501246370572200177100ustar00rootroot00000000000000.TH "sepol_genbools" "3" "11 August 2004" "sds@epoch.ncsc.mil" "SE Linux binary policy API documentation" .SH "NAME" sepol_genbools \- Rewrite a binary policy with different boolean settings .SH "SYNOPSIS" .B #include .sp .BI "int sepol_genbools(void *" data ", size_t "len ", char *" boolpath ); .br .BI "int sepol_genbools_array(void *" data ", size_t " len ", char **" names ", int *" values ", int " nel ); .SH "DESCRIPTION" .B sepol_genbools rewrites a binary policy stored in the memory region described by (data, len) to use the boolean settings specified in the file named by boolpath. The boolean settings are specified by name=value lines where value may be 0 or false to disable or 1 or true to enable. The binary policy is rewritten in place in memory. .B sepol_genbools_array does likewise, but obtains the boolean settings from the parallel arrays (names, values) with nel elements each. .SH "RETURN VALUE" Returns 0 on success or \-1 otherwise, with errno set appropriately. An errno of ENOENT indicates that the boolean file did not exist. An errno of EINVAL indicates that one or more booleans listed in the boolean file was undefined in the policy or had an invalid value specified; in this case, the binary policy is still rewritten but any invalid boolean settings are ignored. libsepol-2.4/man/man3/sepol_genusers.3000066400000000000000000000035651246370572200177430ustar00rootroot00000000000000.TH "sepol_genusers" "3" "15 March 2005" "sds@tycho.nsa.gov" "SE Linux binary policy API documentation" .SH "NAME" sepol_genusers \- Generate a new binary policy image with a customized user configuration .SH "SYNOPSIS" .B #include .sp .BI "int sepol_genusers(void *" data ", size_t "len ", const char *" usersdir ", void *" newdata ", size_t *" newlen); .sp .BI "void sepol_set_delusers(int " on ");" .SH "DESCRIPTION" .B sepol_genusers generates a new binary policy image from an existing binary policy image stored in the memory region described by the starting address .I data and the length .I len and a pair of user configuration files named .B system.users and .B local.users from the directory specified by .I usersdir. The resulting binary policy is placed into dynamically allocated memory and the variables .I newdata and .I newlen are set to refer to the new binary image's starting address and length. The original binary policy image is not modified. By default, .B sepol_genusers will preserve user entries that are defined in the original binary policy image but not defined in the user configuration files. If such user entries should instead by omitted entirely from the new binary policy image, then the .B sepol_set_delusers function may be called with .I on set to 1 prior to calling .B sepol_genusers in order to enable deletion of such users. .SH "RETURN VALUE" Returns 0 on success or \-1 otherwise, with errno set appropriately. An errno of ENOENT indicates that one or both of the user configuration files did not exist. An errno of EINVAL indicates that either the original binary policy image or the generated one were invalid. An errno of ENOMEM indicates that insufficient memory was available to process the original binary policy image or to generate the new policy image. Invalid entries in the user configuration files are skipped with a warning. libsepol-2.4/man/man8/000077500000000000000000000000001246370572200146165ustar00rootroot00000000000000libsepol-2.4/man/man8/chkcon.8000066400000000000000000000031601246370572200161540ustar00rootroot00000000000000.\" 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 . libsepol-2.4/man/man8/genpolbools.8000066400000000000000000000010351246370572200172310ustar00rootroot00000000000000.TH "genpolbools" "8" "11 August 2004" "sds@epoch.ncsc.mil" "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. libsepol-2.4/man/man8/genpolusers.8000066400000000000000000000031331246370572200172550ustar00rootroot00000000000000.\" 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 . libsepol-2.4/src/000077500000000000000000000000001246370572200137675ustar00rootroot00000000000000libsepol-2.4/src/Makefile000066400000000000000000000041221246370572200154260ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr INCLUDEDIR ?= $(PREFIX)/include LIBDIR ?= $(PREFIX)/lib SHLIBDIR ?= $(DESTDIR)/lib RANLIB ?= ranlib LIBBASE ?= $(shell basename $(LIBDIR)) CILDIR ?= ../cil VERSION = $(shell cat ../VERSION) LIBVERSION = 1 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,$(wildcard *.c)) LOBJS= $(patsubst %.c,%.lo,$(wildcard *.c)) CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-format-attribute -O2 override CFLAGS += -I. -I../include -D_GNU_SOURCE ifneq ($(DISABLE_CIL),y) OBJS += $(sort $(patsubst %.c,%.o,$(wildcard $(CILDIR)/src/*.c) $(CIL_GENERATED))) LOBJS += $(sort $(patsubst %.c,%.lo,$(wildcard $(CILDIR)/src/*.c) $(CIL_GENERATED))) override CFLAGS += -I$(CILDIR)/include endif all: $(LIBA) $(LIBSO) $(LIBPC) $(LIBA): $(OBJS) $(AR) rcs $@ $^ $(RANLIB) $@ $(LIBSO): $(LOBJS) $(LIBMAP) $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(LOBJS) -Wl,-soname,$(LIBSO),--version-script=$(LIBMAP),-z,defs ln -sf $@ $(TARGET) $(LIBPC): $(LIBPC).in ../VERSION sed -e 's/@VERSION@/$(VERSION)/; s:@prefix@:$(PREFIX):; s:@libdir@:$(LIBBASE):; 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.c: $(CILDIR)/src/cil_lexer.l $(LEX) -t $< > $@ endif %.o: %.c $(CC) $(CFLAGS) -fPIC -c -o $@ $< %.lo: %.c $(CC) $(CFLAGS) -fPIC -DSHARED -c -o $@ $< install: all test -d $(LIBDIR) || install -m 755 -d $(LIBDIR) install -m 644 $(LIBA) $(LIBDIR) test -d $(SHLIBDIR) || install -m 755 -d $(SHLIBDIR) install -m 755 $(LIBSO) $(SHLIBDIR) test -d $(LIBDIR)/pkgconfig || install -m 755 -d $(LIBDIR)/pkgconfig install -m 644 $(LIBPC) $(LIBDIR)/pkgconfig ln -sf --relative $(SHLIBDIR)/$(LIBSO) $(LIBDIR)/$(TARGET) relabel: /sbin/restorecon $(SHLIBDIR)/$(LIBSO) clean: -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(CIL_GENERATED) indent: ../../scripts/Lindent $(wildcard *.[ch]) libsepol-2.4/src/assertion.c000066400000000000000000000120351246370572200161430ustar00rootroot00000000000000/* 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 "debug.h" 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, const avtab_ptr_t node) { if (avrule->source_filename) { ERR(handle, "neverallow on line %lu of %s (or line %lu of policy.conf) violated by allow %s %s:%s {%s };", avrule->source_line, avrule->source_filename, 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, node->datum.data & curperm->data)); } 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, node->datum.data & curperm->data)); } 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, node->datum.data & curperm->data)); } } static unsigned long check_assertion_helper(sepol_handle_t * handle, policydb_t * p, avtab_t * te_avtab, avtab_t * te_cond_avtab, unsigned int stype, unsigned int ttype, const avrule_t * avrule) { avtab_key_t avkey; avtab_ptr_t node; class_perm_node_t *curperm; unsigned long errors = 0; for (curperm = avrule->perms; curperm != NULL; curperm = curperm->next) { avkey.source_type = stype + 1; avkey.target_type = ttype + 1; avkey.target_class = curperm->tclass; avkey.specified = AVTAB_ALLOWED; for (node = avtab_search_node(te_avtab, &avkey); node != NULL; node = avtab_search_node_next(node, avkey.specified)) { if (node->datum.data & curperm->data) { report_failure(handle, p, avrule, stype, ttype, curperm, node); errors++; } } for (node = avtab_search_node(te_cond_avtab, &avkey); node != NULL; node = avtab_search_node_next(node, avkey.specified)) { if (node->datum.data & curperm->data) { report_failure(handle, p, avrule, stype, ttype, curperm, node); errors++; } } } return errors; } int check_assertions(sepol_handle_t * handle, policydb_t * p, avrule_t * avrules) { avrule_t *a; avtab_t te_avtab, te_cond_avtab; ebitmap_node_t *snode, *tnode; unsigned int i, j; 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; } if (avrules) { if (avtab_init(&te_avtab)) goto oom; if (avtab_init(&te_cond_avtab)) { avtab_destroy(&te_avtab); goto oom; } if (expand_avtab(p, &p->te_avtab, &te_avtab) || expand_avtab(p, &p->te_cond_avtab, &te_cond_avtab)) { avtab_destroy(&te_avtab); avtab_destroy(&te_cond_avtab); goto oom; } } for (a = avrules; a != NULL; a = a->next) { ebitmap_t *stypes = &a->stypes.types; ebitmap_t *ttypes = &a->ttypes.types; if (!(a->specified & AVRULE_NEVERALLOW)) continue; ebitmap_for_each_bit(stypes, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; if (a->flags & RULE_SELF) { errors += check_assertion_helper (handle, p, &te_avtab, &te_cond_avtab, i, i, a); } ebitmap_for_each_bit(ttypes, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; errors += check_assertion_helper (handle, p, &te_avtab, &te_cond_avtab, i, j, a); } } } if (errors) ERR(handle, "%lu neverallow failures occurred", errors); avtab_destroy(&te_avtab); avtab_destroy(&te_cond_avtab); return errors ? -1 : 0; oom: ERR(handle, "Out of memory - unable to check neverallows"); return -1; } libsepol-2.4/src/av_permissions.h000066400000000000000000000002411246370572200171760ustar00rootroot00000000000000/* Used by security_compute_av. */ #define PROCESS__TRANSITION 0x00000002UL #define PROCESS__DYNTRANSITION 0x00800000UL libsepol-2.4/src/avrule_block.c000066400000000000000000000123271246370572200166100ustar00rootroot00000000000000/* 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 /* 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 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 (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++) { ebitmap_destroy(scope->scope + i); } for (i = 0; i < scope->class_perms_len; i++) { 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); uint32_t i; if (scope == NULL) { return 0; } if (scope->scope != SCOPE_DECL) { return 0; } for (i = 0; i < scope->decl_ids_len; i++) { avrule_decl_t *decl = p->decl_val_to_struct[scope->decl_ids[i] - 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; } libsepol-2.4/src/avtab.c000066400000000000000000000324031246370572200152320ustar00rootroot00000000000000 /* 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" /* Based on MurmurHash3, written by Austin Appleby and placed in the * public domain. */ 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) { \ 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; \ } 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; newnode = (avtab_ptr_t) malloc(sizeof(struct avtab_node)); if (newnode == NULL) return NULL; memset(newnode, 0, sizeof(struct avtab_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 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)) 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 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 *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 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 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 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) { 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 avtab_init(avtab_t * h) { h->htable = NULL; h->nel = 0; return 0; } int 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 = 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 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 uint16_t spec_order[] = { AVTAB_ALLOWED, AVTAB_AUDITDENY, AVTAB_AUDITALLOW, AVTAB_TRANSITION, AVTAB_CHANGE, AVTAB_MEMBER }; int 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) { uint16_t buf16[4], enabled; uint32_t buf32[7], items, items2, val; avtab_key_t key; avtab_datum_t datum; unsigned set; unsigned int i; int rc; memset(&key, 0, sizeof(avtab_key_t)); memset(&datum, 0, sizeof(avtab_datum_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]) { 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; } 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 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 = avtab_alloc(a, nel); if (rc) { ERR(fp->handle, "out of memory"); goto bad; } for (i = 0; i < nel; i++) { rc = 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: avtab_destroy(a); return -1; } libsepol-2.4/src/boolean_internal.h000066400000000000000000000007121246370572200174530ustar00rootroot00000000000000#ifndef _SEPOL_BOOLEAN_INTERNAL_H_ #define _SEPOL_BOOLEAN_INTERNAL_H_ #include #include #include "dso.h" hidden_proto(sepol_bool_key_create) hidden_proto(sepol_bool_key_unpack) hidden_proto(sepol_bool_get_name) hidden_proto(sepol_bool_set_name) hidden_proto(sepol_bool_get_value) hidden_proto(sepol_bool_set_value) hidden_proto(sepol_bool_create) hidden_proto(sepol_bool_free) #endif libsepol-2.4/src/boolean_record.c000066400000000000000000000063271246370572200171200ustar00rootroot00000000000000#include #include #include #include "boolean_internal.h" #include "debug.h" struct sepol_bool { /* This boolean's name */ char *name; /* Its value */ int value; }; struct sepol_bool_key { /* This boolean's name */ const 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 = name; *key_ptr = tmp_key; return STATUS_SUCCESS; } hidden_def(sepol_bool_key_create) void sepol_bool_key_unpack(const sepol_bool_key_t * key, const char **name) { *name = key->name; } hidden_def(sepol_bool_key_unpack) 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) { 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; } hidden_def(sepol_bool_get_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; } hidden_def(sepol_bool_set_name) /* Value */ int sepol_bool_get_value(const sepol_bool_t * boolean) { return boolean->value; } hidden_def(sepol_bool_get_value) void sepol_bool_set_value(sepol_bool_t * boolean, int value) { boolean->value = value; } hidden_def(sepol_bool_set_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; } hidden_def(sepol_bool_create) /* 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); } hidden_def(sepol_bool_free) libsepol-2.4/src/booleans.c000066400000000000000000000107031246370572200157360ustar00rootroot00000000000000#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; sepol_bool_key_unpack(key, &cname); name = strdup(cname); value = sepol_bool_get_value(data); if (!name) goto omem; cond_bool_datum_t *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) { const char *name; sepol_bool_key_unpack(key, &name); policydb_t *policydb = &p->p; 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; handle = NULL; 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; 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; } libsepol-2.4/src/conditional.c000066400000000000000000000506311246370572200164430ustar00rootroot00000000000000/* 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" /* 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) printf ("expression result was undefined - disabling all rules.\n"); /* 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; /* becuase 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 */ printf ("Found expr with no bools and only a ! - this should never happen.\n"); 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: i = 0; /* 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 < (0x1U << 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 & (0x1 << j)) ? 1 : 0; } k = cond_evaluate_expr(p, cn->expr); if (k == -1) { printf ("While testing expression, expression result " "was undefined - this should never happen.\n"); return -1; } /* set the bit if expression evaluates true */ if (k) cn->expr_pre_comp |= 0x1 << 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 cond_policydb_init(policydb_t * p) { p->bool_val_to_struct = NULL; p->cond_list = NULL; if (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 cond_policydb_destroy(policydb_t * p) { if (p->bool_val_to_struct != NULL) free(p->bool_val_to_struct); avtab_destroy(&p->te_cond_avtab); cond_list_destroy(p->cond_list); } int 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 **) malloc(p->p_bools.nprim * sizeof(cond_bool_datum_t *)); if (!p->bool_val_to_struct) return -1; return 0; } int cond_destroy_bool(hashtab_key_t key, hashtab_datum_t datum, void *p __attribute__ ((unused))) { if (key) free(key); free(datum); return 0; } int 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; 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 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]); key = malloc(len + 1); if (!key) goto err; rc = next_entry(key, fp, len); if (rc < 0) goto err; key[len] = 0; 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: 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 (avtab_search(&p->te_avtab, k)) { printf ("security: type rule already exists outside of a conditional."); goto err; } /* * 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 = avtab_search_node(&p->te_cond_avtab, k); if (node_ptr) { if (avtab_search_node_next (node_ptr, k->specified)) { printf ("security: too many conflicting type rules."); goto err; } found = 0; for (cur = other; cur != NULL; cur = cur->next) { if (cur->node == node_ptr) { found = 1; break; } } if (!found) { printf ("security: conflicting type rules.\n"); goto err; } } } else { if (avtab_search(&p->te_cond_avtab, k)) { printf ("security: conflicting type rules when adding type rule for true.\n"); goto err; } } } node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d); if (!node_ptr) { printf("security: could not insert rule."); goto err; } node_ptr->parse_context = (void *)1; list = malloc(sizeof(cond_av_list_t)); if (!list) goto err; 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; err: cond_av_list_destroy(data->head); data->head = NULL; return -1; } 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; len = 0; 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 = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data); if (rc) 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) { printf ("security: conditional expressions uses unknown operator.\n"); return 0; } if (expr->bool > p->p_bools.nprim) { printf ("security: conditional expressions uses unknown bool.\n"); 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]); len = 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 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 = 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 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 = avtab_search_node(ctab, key); node != NULL; node = 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; } libsepol-2.4/src/constraint.c000066400000000000000000000027131246370572200163220ustar00rootroot00000000000000/* 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 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) { if (expr != NULL) { ebitmap_destroy(&expr->names); type_set_destroy(expr->type_names); free(expr->type_names); free(expr); } } libsepol-2.4/src/context.c000066400000000000000000000177671246370572200156410ustar00rootroot00000000000000#include #include #include #include #include #include "context_internal.h" #include "debug.h" #include "context.h" #include "handle.h" #include "mls.h" /* ----- Compatibility ---- */ int 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((const sepol_security_context_t)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; int ret = 1; 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 (!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 (!ebitmap_get_bit(&usrdatum->cache, c->role - 1)) /* user may not be associated with role */ return 0; } if (!mls_context_isvalid(p, c)) return 0; return ret; } /* * 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 += 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]); 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 && (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; /* sepol_context_from_string expects a NULL-terminated string */ con_cpy = malloc(con_str_len + 1); if (!con_cpy) goto omem; 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; omem: ERR(handle, "out of memory"); 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; } libsepol-2.4/src/context.h000066400000000000000000000023471246370572200156320ustar00rootroot00000000000000#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 libsepol-2.4/src/context_internal.h000066400000000000000000000011421246370572200175160ustar00rootroot00000000000000#ifndef _SEPOL_CONTEXT_INTERNAL_H_ #define _SEPOL_CONTEXT_INTERNAL_H_ #include #include "dso.h" hidden_proto(sepol_context_clone) hidden_proto(sepol_context_create) hidden_proto(sepol_context_free) hidden_proto(sepol_context_from_string) hidden_proto(sepol_context_get_mls) hidden_proto(sepol_context_get_role) hidden_proto(sepol_context_get_type) hidden_proto(sepol_context_get_user) hidden_proto(sepol_context_set_mls) hidden_proto(sepol_context_set_role) hidden_proto(sepol_context_set_type) hidden_proto(sepol_context_set_user) #endif libsepol-2.4/src/context_record.c000066400000000000000000000137421246370572200171640ustar00rootroot00000000000000#include #include #include #include #include "context_internal.h" #include "debug.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; } hidden_def(sepol_context_get_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; } hidden_def(sepol_context_set_user) /* Role */ const char *sepol_context_get_role(const sepol_context_t * con) { return con->role; } hidden_def(sepol_context_get_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; } hidden_def(sepol_context_set_role) /* Type */ const char *sepol_context_get_type(const sepol_context_t * con) { return con->type; } hidden_def(sepol_context_get_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; } hidden_def(sepol_context_set_type) /* MLS */ const char *sepol_context_get_mls(const sepol_context_t * con) { return con->mls; } hidden_def(sepol_context_get_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; } hidden_def(sepol_context_set_mls) /* 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\n"); return STATUS_ERR; } con->user = NULL; con->role = NULL; con->type = NULL; con->mls = NULL; *con_ptr = con; return STATUS_SUCCESS; } hidden_def(sepol_context_create) /* 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; } hidden_def(sepol_context_clone) /* 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); } hidden_def(sepol_context_free) 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; } hidden_def(sepol_context_from_string) int sepol_context_to_string(sepol_handle_t * handle, const sepol_context_t * con, char **str_ptr) { int rc; const int user_sz = strlen(con->user); const int role_sz = strlen(con->role); const int type_sz = strlen(con->type); const int mls_sz = (con->mls) ? strlen(con->mls) : 0; const int total_sz = user_sz + role_sz + type_sz + mls_sz + ((con->mls) ? 3 : 2); char *str = (char *)malloc(total_sz + 1); if (!str) goto omem; if (con->mls) { rc = snprintf(str, total_sz + 1, "%s:%s:%s:%s", con->user, con->role, con->type, con->mls); if (rc < 0 || (rc >= total_sz + 1)) { ERR(handle, "print error"); goto err; } } else { rc = snprintf(str, total_sz + 1, "%s:%s:%s", con->user, con->role, con->type); if (rc < 0 || (rc >= total_sz + 1)) { ERR(handle, "print error"); goto err; } } *str_ptr = str; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: ERR(handle, "could not convert context to string"); free(str); return STATUS_ERR; } libsepol-2.4/src/debug.c000066400000000000000000000032611246370572200152230ustar00rootroot00000000000000#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; } hidden_def(sepol_msg_get_level) const char *sepol_msg_get_channel(sepol_handle_t * handle) { return handle->msg_channel; } hidden_def(sepol_msg_get_channel) const char *sepol_msg_get_fname(sepol_handle_t * handle) { return handle->msg_fname; } hidden_def(sepol_msg_get_fname) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif void hidden sepol_msg_default_handler(void *varg __attribute__ ((unused)), sepol_handle_t * handle, const char *fmt, ...) { FILE *stream = NULL; 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_list ap; va_start(ap, fmt); vfprintf(stream, fmt, ap); va_end(ap); fprintf(stream, "\n"); varg = NULL; } 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; } libsepol-2.4/src/debug.h000066400000000000000000000046171246370572200152360ustar00rootroot00000000000000/* * 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 "dso.h" #include "handle.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__) #define WARN(handle, ...) \ msg_write(handle, SEPOL_MSG_WARN, "libsepol", \ __FUNCTION__, __VA_ARGS__) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif extern void hidden sepol_msg_default_handler(void *varg, sepol_handle_t * msg, const char *fmt, ...); extern struct sepol_handle sepol_compat_handle; hidden_proto(sepol_msg_get_channel) hidden_proto(sepol_msg_get_fname) hidden_proto(sepol_msg_get_level) #endif libsepol-2.4/src/dso.h000066400000000000000000000012041246370572200147220ustar00rootroot00000000000000#ifndef _SEPOL_DSO_H #define _SEPOL_DSO_H 1 #ifdef SHARED # define hidden __attribute__ ((visibility ("hidden"))) # define hidden_proto(fct) __hidden_proto (fct, fct##_internal) # define __hidden_proto(fct, internal) \ extern __typeof (fct) internal; \ extern __typeof (fct) fct __asm (#internal) hidden; # if defined(__alpha__) || defined(__mips__) # define hidden_def(fct) \ asm (".globl " #fct "\n" #fct " = " #fct "_internal"); # else # define hidden_def(fct) \ asm (".globl " #fct "\n.set " #fct ", " #fct "_internal"); #endif #else # define hidden # define hidden_proto(fct) # define hidden_def(fct) #endif #endif libsepol-2.4/src/ebitmap.c000066400000000000000000000204471246370572200155630ustar00rootroot00000000000000 /* 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) { ebitmap_node_t *n1, *n2, *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) { 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; ebitmap_destroy(dst); dst->node = tmp.node; dst->highbit = tmp.highbit; return 0; } int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2) { unsigned int i, length = min(ebitmap_length(e1), ebitmap_length(e2)); ebitmap_init(dst); for (i=0; i < length; i++) { if (ebitmap_get_bit(e1, i) && ebitmap_get_bit(e2, i)) { int rc = ebitmap_set_bit(dst, i, 1); if (rc < 0) return rc; } } return 0; } int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, 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 = ebitmap_get_bit(e1, i) ^ ebitmap_get_bit(e2, i); int rc = ebitmap_set_bit(dst, i, val); if (rc < 0) return rc; } return 0; } int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit) { unsigned int i; ebitmap_init(dst); for (i=0; i < maxbit; i++) { int val = ebitmap_get_bit(e1, i); int rc = ebitmap_set_bit(dst, i, !val); if (rc < 0) return rc; } return 0; } int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit) { ebitmap_t e3; ebitmap_init(dst); int rc = ebitmap_not(&e3, e2, maxbit); if (rc < 0) return rc; rc = ebitmap_and(dst, e1, &e3); ebitmap_destroy(&e3); if (rc < 0) return rc; return 0; } unsigned int ebitmap_cardinality(ebitmap_t *e1) { unsigned int i, count = 0; for (i=ebitmap_startbit(e1); i < ebitmap_length(e1); i++) if (ebitmap_get_bit(e1, i)) count++; return count; } int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2) { if (ebitmap_cmp(e1, e2)) return 0; ebitmap_t tmp; int rc = ebitmap_xor(&tmp, e1, e2); if (rc < 0) return -1; int distance = ebitmap_cardinality(&tmp); ebitmap_destroy(&tmp); return distance; } int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2) { 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 ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src) { ebitmap_node_t *n, *new, *prev; ebitmap_init(dst); n = src->node; prev = 0; while (n) { new = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); if (!new) { 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 ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2) { 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_get_bit(const ebitmap_t * e, unsigned int bit) { 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 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; } void 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 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) { printf ("security: ebitmap: map size %d does not match my size %zu (high bit was %d)\n", mapsize, MAPSIZE, e->highbit); goto bad; } if (!e->highbit) { e->node = NULL; goto ok; } if (e->highbit & (MAPSIZE - 1)) { printf ("security: ebitmap: high bit (%d) is not a multiple of the map size (%zu)\n", e->highbit, MAPSIZE); goto bad; } l = NULL; for (i = 0; i < count; i++) { rc = next_entry(buf, fp, sizeof(uint32_t)); if (rc < 0) { printf("security: ebitmap: truncated map\n"); goto bad; } n = (ebitmap_node_t *) malloc(sizeof(ebitmap_node_t)); if (!n) { printf("security: ebitmap: out of memory\n"); rc = -ENOMEM; goto bad; } memset(n, 0, sizeof(ebitmap_node_t)); n->startbit = le32_to_cpu(buf[0]); if (n->startbit & (MAPSIZE - 1)) { printf ("security: ebitmap start bit (%d) is not a multiple of the map size (%zu)\n", n->startbit, MAPSIZE); goto bad_free; } if (n->startbit > (e->highbit - MAPSIZE)) { printf ("security: ebitmap start bit (%d) is beyond the end of the bitmap (%zu)\n", n->startbit, (e->highbit - MAPSIZE)); goto bad_free; } rc = next_entry(&map, fp, sizeof(uint64_t)); if (rc < 0) { printf("security: ebitmap: truncated map\n"); goto bad_free; } n->map = le64_to_cpu(map); if (!n->map) { printf ("security: ebitmap: null map in ebitmap (startbit %d)\n", n->startbit); goto bad_free; } if (l) { if (n->startbit <= l->startbit) { printf ("security: ebitmap: start bit %d comes after start bit %d\n", n->startbit, l->startbit); goto bad_free; } l->next = n; } else e->node = n; l = n; } ok: rc = 0; out: return rc; bad_free: free(n); bad: if (!rc) rc = -EINVAL; ebitmap_destroy(e); goto out; } /* FLASK */ libsepol-2.4/src/expand.c000066400000000000000000002464561246370572200154330ustar00rootroot00000000000000/* Authors: Karl MacMillan * Jason Tang * Joshua Brindle * * 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 "context.h" #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_bit(src, tnode, i) { if (!ebitmap_node_get_bit(tnode, i)) continue; if (!map[i]) continue; if (ebitmap_set_bit(dst, map[i] - 1, 1)) return -1; } 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 (ebitmap_set_bit(&state->out->permissive_map, new_type->s.value, 1)) { ERR(state->handle, "Out of memory!\n"); 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; } 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 (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 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 (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; } } 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 (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 (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 (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 (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; ebitmap_destroy(&role->dominates); if (ebitmap_cpy(&role->dominates, &mapped_roles)) return -1; 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!"); ebitmap_destroy(&mapped_roles); return -1; } ebitmap_destroy(&mapped_roles); ebitmap_for_each_bit(&role->roles, rnode, i) { if (ebitmap_node_get_bit(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)) { 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!"); ebitmap_destroy(&tmp_union_types); return -1; } 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; 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.\n", __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 (!ebitmap_get_bit(&levdatum->level->cat, i)) { ERR(h, "Category %s can not be associate with " "level %s", p->p_cat_val_to_name[i], p->p_sens_val_to_name[l->sens - 1]); } if (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_semantic_level_destroy(&sr->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!"); ebitmap_destroy(&tmp_union); return -1; } if (ebitmap_union(&new_user->roles.roles, &tmp_union)) { ERR(state->handle, "Out of memory!"); ebitmap_destroy(&tmp_union); return -1; } 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_bit(&roles, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; ebitmap_for_each_bit(&new_roles, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; /* 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; } } ebitmap_destroy(&roles); 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_bit(&roles, rnode, i) { if (!ebitmap_node_get_bit(rnode, i)) continue; ebitmap_for_each_bit(&types, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; ebitmap_for_each_bit(&cur->classes, cnode, k) { if (!ebitmap_node_get_bit(cnode, k)) continue; 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; } } } ebitmap_destroy(&roles); ebitmap_destroy(&types); cur = cur->next; } return 0; } static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules) { unsigned int i, j; filename_trans_t *new_trans, *cur_trans; filename_trans_rule_t *cur_rule; ebitmap_t stypes, ttypes; ebitmap_node_t *snode, *tnode; cur_rule = rules; while (cur_rule) { uint32_t mapped_otype; 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; } mapped_otype = state->typemap[cur_rule->otype - 1]; ebitmap_for_each_bit(&stypes, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; ebitmap_for_each_bit(&ttypes, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; cur_trans = state->out->filename_trans; while (cur_trans) { if ((cur_trans->stype == i + 1) && (cur_trans->ttype == j + 1) && (cur_trans->tclass == cur_rule->tclass) && (!strcmp(cur_trans->name, cur_rule->name))) { /* duplicate rule, who cares */ if (cur_trans->otype == mapped_otype) break; ERR(state->handle, "Conflicting name-based type_transition %s %s:%s \"%s\": %s vs %s", state->out->p_type_val_to_name[i], state->out->p_type_val_to_name[j], state->out->p_class_val_to_name[cur_trans->tclass - 1], cur_trans->name, state->out->p_type_val_to_name[cur_trans->otype - 1], state->out->p_type_val_to_name[mapped_otype - 1]); return -1; } cur_trans = cur_trans->next; } /* duplicate rule, who cares */ if (cur_trans) continue; new_trans = malloc(sizeof(*new_trans)); if (!new_trans) { ERR(state->handle, "Out of memory!"); return -1; } memset(new_trans, 0, sizeof(*new_trans)); new_trans->next = state->out->filename_trans; state->out->filename_trans = new_trans; new_trans->name = strdup(cur_rule->name); if (!new_trans->name) { ERR(state->handle, "Out of memory!"); return -1; } new_trans->stype = i + 1; new_trans->ttype = j + 1; new_trans->tclass = cur_rule->tclass; new_trans->otype = mapped_otype; } } ebitmap_destroy(&stypes); 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, *check_rt = state->out->range_tr; mls_range_t exp_range; int rc = -1; if (mls_semantic_range_expand(trange, &exp_range, state->out, state->handle)) goto out; /* check for duplicates/conflicts */ while (check_rt) { if ((check_rt->source_type == stype) && (check_rt->target_type == ttype) && (check_rt->target_class == tclass)) { if (mls_range_eq(&check_rt->target_range, &exp_range)) { /* duplicate */ break; } else { /* 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 out; } } check_rt = check_rt->next; } if (check_rt) { /* this is a dup - skip */ rc = 0; goto out; } rt = (range_trans_t *) calloc(1, sizeof(range_trans_t)); if (!rt) { ERR(state->handle, "Out of memory!"); goto out; } rt->next = state->out->range_tr; state->out->range_tr = rt; rt->source_type = stype; rt->target_type = ttype; rt->target_class = tclass; if (mls_range_cpy(&rt->target_range, &exp_range)) { ERR(state->handle, "Out of memory!"); goto out; } rc = 0; out: mls_range_destroy(&exp_range); return rc; } 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)) { ebitmap_destroy(&stypes); ERR(state->handle, "Out of memory!"); return -1; } /* loop on source type */ ebitmap_for_each_bit(&stypes, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; /* loop on target type */ ebitmap_for_each_bit(&ttypes, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; /* loop on target class */ ebitmap_for_each_bit(&rule->tclasses, cnode, k) { if (!ebitmap_node_get_bit(cnode, k)) continue; if (exp_rangetr_helper(i + 1, j + 1, k + 1, &rule->trange, state)) { ebitmap_destroy(&stypes); ebitmap_destroy(&ttypes); return -1; } } } } ebitmap_destroy(&stypes); 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) { avtab_ptr_t node; avtab_datum_t avdatum; cond_av_list_t *nl; node = 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 = avtab_search_node_next(node, key->specified); } } if (!node) { memset(&avdatum, 0, sizeof avdatum); /* this is used to get the node - insertion is actually unique */ node = 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; } #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, spec = 0; if (specified & AVRULE_TRANSITION) { spec = AVTAB_TRANSITION; } else if (specified & AVRULE_MEMBER) { spec = AVTAB_MEMBER; } else if (specified & AVRULE_CHANGE) { spec = AVTAB_CHANGE; } else { assert(0); /* unreachable */ } cur = perms; while (cur) { uint32_t remapped_data = typemap ? typemap[cur->data - 1] : cur->data; avkey.source_type = stype + 1; avkey.target_type = ttype + 1; avkey.target_class = cur->tclass; avkey.specified = spec; conflict = 0; /* check to see if the expanded TE already exists -- * either in the global scope or in another * conditional AV tab */ node = avtab_search_node(&p->te_avtab, &avkey); if (node) { conflict = 1; } else { node = 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); if (!node) return -1; if (enabled) { node->key.specified |= AVTAB_ENABLED; } else { node->key.specified &= ~AVTAB_ENABLED; } avdatump = &node->datum; if (specified & AVRULE_TRANSITION) { avdatump->data = remapped_data; } else if (specified & AVRULE_MEMBER) { avdatump->data = remapped_data; } else if (specified & AVRULE_CHANGE) { avdatump->data = remapped_data; } else { assert(0); /* should never occur */ } cur = cur->next; } return EXPAND_RULE_SUCCESS; } 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) { avtab_key_t avkey; avtab_datum_t *avdatump; avtab_ptr_t node; class_perm_node_t *cur; uint32_t spec = 0; if (specified & AVRULE_ALLOWED) { spec = AVTAB_ALLOWED; } else if (specified & AVRULE_AUDITALLOW) { spec = AVTAB_AUDITALLOW; } else if (specified & AVRULE_AUDITDENY) { spec = AVTAB_AUDITDENY; } else if (specified & AVRULE_DONTAUDIT) { if (handle && handle->disable_dontaudit) return EXPAND_RULE_SUCCESS; spec = AVTAB_AUDITDENY; } else if (specified & AVRULE_NEVERALLOW) { spec = AVTAB_NEVERALLOW; } else { assert(0); /* unreachable */ } cur = perms; while (cur) { avkey.source_type = stype + 1; avkey.target_type = ttype + 1; avkey.target_class = cur->tclass; avkey.specified = spec; node = find_avtab_node(handle, avtab, &avkey, cond); if (!node) return EXPAND_RULE_ERROR; if (enabled) { node->key.specified |= AVTAB_ENABLED; } else { node->key.specified &= ~AVTAB_ENABLED; } avdatump = &node->datum; if (specified & AVRULE_ALLOWED) { avdatump->data |= cur->data; } else if (specified & AVRULE_AUDITALLOW) { avdatump->data |= cur->data; } else if (specified & AVRULE_NEVERALLOW) { avdatump->data |= cur->data; } else if (specified & 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; } else if (specified & AVRULE_DONTAUDIT) { if (avdatump->data) avdatump->data &= ~cur->data; else avdatump->data = ~cur->data; } else { assert(0); /* should never occur */ } 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_bit(stypes, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; if (source_rule->flags & RULE_SELF) { if (source_rule->specified & AVRULE_AV) { retval = expand_avrule_helper(handle, source_rule->specified, cond, i, i, source_rule->perms, dest_avtab, enabled); 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_bit(ttypes, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; if (source_rule->specified & AVRULE_AV) { retval = expand_avrule_helper(handle, source_rule->specified, cond, i, j, source_rule->perms, dest_avtab, enabled); 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; 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); ebitmap_destroy(&stypes); 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) { 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: if (c->context[0].user == 0) { ERR(state->handle, "Missing context for %s initial sid", c->u.name); return -1; } 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; 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) { 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: if (c->context[0].user == 0) { ERR(state->handle, "Missing context for %s initial sid", c->u.name); return -1; } 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_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; type = (type_datum_t *) datum; if (type->flavor == TYPE_ATTRIB) { if (ebitmap_cpy(&p->attr_type_map[type->s.value - 1], &type->types)) { ERR(state->handle, "Out of memory!"); return -1; } ebitmap_for_each_bit(&type->types, tnode, i) { if (!ebitmap_node_get_bit(tnode, i)) continue; if (ebitmap_set_bit(&p->type_attr_map[i], type->s.value - 1, 1)) { ERR(state->handle, "Out of memory!"); return -1; } } } return 0; } /* 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) 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); ebitmap_destroy(&stypes); 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 (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_bit(&x->roles, rnode, i) { if (ebitmap_node_get_bit(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 (ebitmap_set_bit(&roles, i, 1)) goto bad; } } } if (map_ebitmap(&roles, &mapped_roles, rolemap)) goto bad; } else { if (ebitmap_cpy(&mapped_roles, &x->roles)) goto bad; } ebitmap_for_each_bit(&mapped_roles, rnode, i) { if (ebitmap_node_get_bit(rnode, i)) { if (ebitmap_set_bit(r, i, 1)) goto bad; } } ebitmap_destroy(&mapped_roles); ebitmap_destroy(&roles); /* if role is to be complimented, invert the entire bitmap here */ if (x->flags & ROLE_COMP) { for (i = 0; i < ebitmap_length(r); i++) { if (ebitmap_get_bit(r, i)) { if (ebitmap_set_bit(r, i, 0)) return -1; } else { if (ebitmap_set_bit(r, i, 1)) return -1; } } } return 0; bad: ebitmap_destroy(&mapped_roles); 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; ebitmap_init(&types); ebitmap_init(t); if (alwaysexpand || ebitmap_length(&set->negset) || set->flags) { /* First go through the types and OR all the attributes to types */ ebitmap_for_each_bit(&set->types, tnode, i) { if (ebitmap_node_get_bit(tnode, i)) { if (p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { if (ebitmap_union (&types, &p->type_val_to_struct[i]-> types)) { return -1; } } else { if (ebitmap_set_bit(&types, i, 1)) { return -1; } } } } } else { /* No expansion of attributes, just copy the set as is. */ if (ebitmap_cpy(&types, &set->types)) return -1; } /* Now do the same thing for negset */ ebitmap_init(&neg_types); ebitmap_for_each_bit(&set->negset, tnode, i) { if (ebitmap_node_get_bit(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)) { return -1; } } else { if (ebitmap_set_bit(&neg_types, i, 1)) { return -1; } } } } if (set->flags & TYPE_STAR) { /* set all types not in neg_types */ for (i = 0; i < p->p_types.nprim; i++) { if (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 (ebitmap_set_bit(t, i, 1)) return -1; } goto out; } ebitmap_for_each_bit(&types, tnode, i) { if (ebitmap_node_get_bit(tnode, i) && (!ebitmap_get_bit(&neg_types, i))) if (ebitmap_set_bit(t, i, 1)) return -1; } 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(!ebitmap_get_bit(t, i)); continue; } if (ebitmap_get_bit(t, i)) { if (ebitmap_set_bit(t, i, 0)) return -1; } else { if (ebitmap_set_bit(t, i, 1)) return -1; } } } out: ebitmap_destroy(&types); ebitmap_destroy(&neg_types); return 0; } 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; 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 = AVRULE_NEVERALLOW; 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 (ebitmap_cpy(&avrule->stypes.types, &stypes)) goto err; if (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; } /* 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; } ebitmap_destroy(&stypes); ebitmap_destroy(&ttypes); return 0; err: ebitmap_destroy(&stypes); ebitmap_destroy(&ttypes); ebitmap_destroy(&avrule->stypes.types); 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(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 (avtab_alloc(&state->out->te_avtab, MAX_AVTAB_SIZE)) { ERR(state->handle, "Out of Memory!"); return -1; } if (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) { /* 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) { 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; /* 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 (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 (hashtab_map(state.base->p_types.table, type_copy_callback, &state)) { goto cleanup; } /* convert attribute type sets */ if (hashtab_map (state.base->p_types.table, attr_convert_callback, &state)) { goto cleanup; } /* copy commons */ if (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 (hashtab_map (state.base->p_classes.table, class_copy_callback, &state)) { goto cleanup; } /* copy type bounds */ if (hashtab_map(state.base->p_types.table, type_bounds_copy_callback, &state)) goto cleanup; /* copy aliases */ if (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 (hashtab_map(state.base->p_roles.table, role_copy_callback, &state)) goto cleanup; if (hashtab_map(state.base->p_roles.table, role_bounds_copy_callback, &state)) goto cleanup; /* escalate the type_set_t in a role attribute to all regular roles * that belongs to it. */ if (hashtab_map(state.base->p_roles.table, role_fix_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 (hashtab_map(state.base->p_levels.table, sens_copy_callback, &state)) goto cleanup; if (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 (hashtab_map(state.base->p_users.table, user_copy_callback, &state)) goto cleanup; if (hashtab_map(state.base->p_users.table, user_bounds_copy_callback, &state)) goto cleanup; /* copy bools */ if (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 (hashtab_map (decl->p_types.table, attr_convert_callback, &state)) { goto cleanup; } /* copy roles */ if (hashtab_map (decl->p_roles.table, role_copy_callback, &state)) goto cleanup; /* copy users */ if (hashtab_map (decl->p_users.table, user_copy_callback, &state)) goto cleanup; } /* remap role dominates bitmaps */ if (hashtab_map(state.out->p_roles.table, role_remap_dominates, &state)) { goto cleanup; } if (copy_and_expand_avrule_block(&state) < 0) { ERR(handle, "Error during expand"); goto cleanup; } /* copy constraints */ if (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 = malloc(state.out->p_types.nprim * sizeof(ebitmap_t)); state.out->type_attr_map = malloc(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++) { ebitmap_init(&state.out->type_attr_map[i]); ebitmap_init(&state.out->attr_type_map[i]); /* add the type itself as the degenerate case */ if (ebitmap_set_bit(&state.out->type_attr_map[i], i, 1)) { ERR(handle, "Out of memory!"); goto cleanup; } } if (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; int rc; node = avtab_search_node(a, k); if (!node) { rc = avtab_insert(a, k, d); if (rc) ERR(NULL, "Out of memory!"); return rc; } if ((k->specified & AVTAB_ENABLED) != (node->key.specified & AVTAB_ENABLED)) { node = avtab_insert_nonunique(a, k, d); if (!node) { ERR(NULL, "Out of memory!"); return -1; } 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; } 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_bit(tattr, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; 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_bit(sattr, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; 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_bit(sattr, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; ebitmap_for_each_bit(tattr, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; 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 (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 = avtab_search_node(expa, k); if (!node || (k->specified & AVTAB_ENABLED) != (node->key.specified & AVTAB_ENABLED)) { node = 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; } 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_bit(tattr, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; 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_bit(sattr, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; 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_bit(sattr, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; ebitmap_for_each_bit(tattr, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; 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 (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; } libsepol-2.4/src/genbools.c000066400000000000000000000124021246370572200157420ustar00rootroot00000000000000#include #include #include #include #include #include #include "debug.h" #include "private.h" #include "dso.h" /* -- Deprecated -- */ static char *strtrim(char *dest, char *source, int size) { int i = 0; char *ptr = source; i = 0; while (isspace(*ptr) && i < size) { ptr++; i++; } strncpy(dest, ptr, size); for (i = strlen(dest) - 1; i > 0; i--) { if (!isspace(dest[i])) break; } dest[i + 1] = '\0'; return dest; } static int process_boolean(char *buffer, char *name, int namesize, int *val) { char name1[BUFSIZ]; char *ptr = NULL; char *tok = strtok_r(buffer, "=", &ptr); if (tok) { strncpy(name1, tok, BUFSIZ - 1); strtrim(name, name1, namesize - 1); if (name[0] == '#') return 0; tok = strtok_r(NULL, "\0", &ptr); if (tok) { while (isspace(*tok)) tok++; *val = -1; if (isdigit(tok[0])) *val = atoi(tok); else if (!strncasecmp(tok, "true", sizeof("true") - 1)) *val = 1; else if (!strncasecmp (tok, "false", sizeof("false") - 1)) *val = 0; if (*val != 0 && *val != 1) { ERR(NULL, "illegal value for boolean " "%s=%s", name, tok); return -1; } } } return 1; } static int load_booleans(struct policydb *policydb, const char *path, int *changesp) { FILE *boolf; char *buffer = NULL; size_t size = 0; char localbools[BUFSIZ]; char name[BUFSIZ]; int val; int errors = 0, changes = 0; struct cond_bool_datum *datum; boolf = fopen(path, "r"); if (boolf == NULL) goto localbool; #ifdef DARWIN if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { ERR(NULL, "out of memory"); return -1; } while(fgets(buffer, 255, boolf) != NULL) { #else while (getline(&buffer, &size, boolf) > 0) { #endif int ret = process_boolean(buffer, name, sizeof(name), &val); if (ret == -1) errors++; if (ret == 1) { datum = hashtab_search(policydb->p_bools.table, name); if (!datum) { ERR(NULL, "unknown boolean %s", name); errors++; continue; } if (datum->state != val) { datum->state = val; changes++; } } } fclose(boolf); localbool: snprintf(localbools, sizeof(localbools), "%s.local", path); boolf = fopen(localbools, "r"); if (boolf != NULL) { #ifdef DARWIN while(fgets(buffer, 255, boolf) != NULL) { #else while (getline(&buffer, &size, boolf) > 0) { #endif int ret = process_boolean(buffer, name, sizeof(name), &val); if (ret == -1) errors++; if (ret == 1) { datum = hashtab_search(policydb->p_bools.table, name); if (!datum) { ERR(NULL, "unknown boolean %s", name); errors++; continue; } if (datum->state != val) { datum->state = val; changes++; } } } fclose(boolf); } free(buffer); if (errors) errno = EINVAL; *changesp = changes; return errors ? -1 : 0; } int sepol_genbools(void *data, size_t len, char *booleans) { struct policydb policydb; struct policy_file pf; int rc, changes = 0; if (policydb_init(&policydb)) goto err; if (policydb_from_image(NULL, data, len, &policydb) < 0) goto err; if (load_booleans(&policydb, booleans, &changes) < 0) { WARN(NULL, "error while reading %s", booleans); } if (!changes) goto out; if (evaluate_conds(&policydb) < 0) { ERR(NULL, "error while re-evaluating conditionals"); errno = EINVAL; goto err_destroy; } policy_file_init(&pf); pf.type = PF_USE_MEMORY; pf.data = data; pf.len = len; rc = policydb_write(&policydb, &pf); if (rc) { ERR(NULL, "unable to write new binary policy image"); errno = EINVAL; goto err_destroy; } out: policydb_destroy(&policydb); return 0; err_destroy: policydb_destroy(&policydb); err: return -1; } int hidden sepol_genbools_policydb(policydb_t * policydb, const char *booleans) { int rc, changes = 0; rc = load_booleans(policydb, booleans, &changes); if (!rc && changes) rc = evaluate_conds(policydb); if (rc) errno = EINVAL; return rc; } /* -- End Deprecated -- */ int sepol_genbools_array(void *data, size_t len, char **names, int *values, int nel) { struct policydb policydb; struct policy_file pf; int rc, i, errors = 0; struct cond_bool_datum *datum; /* Create policy database from image */ if (policydb_init(&policydb)) goto err; if (policydb_from_image(NULL, data, len, &policydb) < 0) goto err; for (i = 0; i < nel; i++) { datum = hashtab_search(policydb.p_bools.table, names[i]); if (!datum) { ERR(NULL, "boolean %s no longer in policy", names[i]); errors++; continue; } if (values[i] != 0 && values[i] != 1) { ERR(NULL, "illegal value %d for boolean %s", values[i], names[i]); errors++; continue; } datum->state = values[i]; } if (evaluate_conds(&policydb) < 0) { ERR(NULL, "error while re-evaluating conditionals"); errno = EINVAL; goto err_destroy; } policy_file_init(&pf); pf.type = PF_USE_MEMORY; pf.data = data; pf.len = len; rc = policydb_write(&policydb, &pf); if (rc) { ERR(NULL, "unable to write binary policy"); errno = EINVAL; goto err_destroy; } if (errors) { errno = EINVAL; goto err_destroy; } policydb_destroy(&policydb); return 0; err_destroy: policydb_destroy(&policydb); err: return -1; } libsepol-2.4/src/genusers.c000066400000000000000000000146141246370572200157740ustar00rootroot00000000000000#include #include #include #include #include #include #ifndef DARWIN #include #endif #include #include "debug.h" #include "private.h" #include "dso.h" #include "mls.h" /* -- Deprecated -- */ void sepol_set_delusers(int on __attribute((unused))) { WARN(NULL, "Deprecated interface"); } #undef BADLINE #define BADLINE() { \ ERR(NULL, "invalid entry %s (%s:%u)", \ buffer, path, lineno); \ continue; \ } static int load_users(struct policydb *policydb, const char *path) { FILE *fp; char *buffer = NULL, *p, *q, oldc; size_t len = 0; ssize_t nread; unsigned lineno = 0, islist = 0, bit; user_datum_t *usrdatum; role_datum_t *roldatum; ebitmap_node_t *rnode; fp = fopen(path, "r"); if (fp == NULL) return -1; #ifdef DARWIN if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { ERR(NULL, "out of memory"); return -1; } while(fgets(buffer, 255, fp) != NULL) { #else __fsetlocking(fp, FSETLOCKING_BYCALLER); while ((nread = getline(&buffer, &len, fp)) > 0) { #endif lineno++; if (buffer[nread - 1] == '\n') buffer[nread - 1] = 0; p = buffer; while (*p && isspace(*p)) p++; if (!(*p) || *p == '#') continue; if (strncasecmp(p, "user", 4)) BADLINE(); p += 4; if (!isspace(*p)) BADLINE(); while (*p && isspace(*p)) p++; if (!(*p)) BADLINE(); q = p; while (*p && !isspace(*p)) p++; if (!(*p)) BADLINE(); *p++ = 0; usrdatum = hashtab_search(policydb->p_users.table, q); if (usrdatum) { /* Replacing an existing user definition. */ ebitmap_destroy(&usrdatum->roles.roles); ebitmap_init(&usrdatum->roles.roles); } else { char *id = strdup(q); if (!id) { ERR(NULL, "out of memory"); free(buffer); fclose(fp); return -1; } /* Adding a new user definition. */ usrdatum = malloc(sizeof(user_datum_t)); if (!usrdatum) { ERR(NULL, "out of memory"); free(buffer); free(id); fclose(fp); return -1; } user_datum_init(usrdatum); usrdatum->s.value = ++policydb->p_users.nprim; if (hashtab_insert(policydb->p_users.table, id, (hashtab_datum_t) usrdatum)) { ERR(NULL, "out of memory"); free(buffer); free(id); user_datum_destroy(usrdatum); free(usrdatum); fclose(fp); return -1; } } while (*p && isspace(*p)) p++; if (!(*p)) BADLINE(); if (strncasecmp(p, "roles", 5)) BADLINE(); p += 5; if (!isspace(*p)) BADLINE(); while (*p && isspace(*p)) p++; if (!(*p)) BADLINE(); if (*p == '{') { islist = 1; p++; } else islist = 0; oldc = 0; do { while (*p && isspace(*p)) p++; if (!(*p)) break; q = p; while (*p && *p != ';' && *p != '}' && !isspace(*p)) p++; if (!(*p)) break; if (*p == '}') islist = 0; oldc = *p; *p++ = 0; if (!q[0]) break; roldatum = hashtab_search(policydb->p_roles.table, q); if (!roldatum) { ERR(NULL, "undefined role %s (%s:%u)", q, path, lineno); continue; } /* Set the role and every role it dominates */ ebitmap_for_each_bit(&roldatum->dominates, rnode, bit) { if (ebitmap_node_get_bit(rnode, bit)) if (ebitmap_set_bit (&usrdatum->roles.roles, bit, 1)) { ERR(NULL, "out of memory"); free(buffer); fclose(fp); return -1; } } } while (islist); if (oldc == 0) BADLINE(); if (policydb->mls) { context_struct_t context; char *scontext, *r, *s; while (*p && isspace(*p)) p++; if (!(*p)) BADLINE(); if (strncasecmp(p, "level", 5)) BADLINE(); p += 5; if (!isspace(*p)) BADLINE(); while (*p && isspace(*p)) p++; if (!(*p)) BADLINE(); q = p; while (*p && strncasecmp(p, "range", 5)) p++; if (!(*p)) BADLINE(); *--p = 0; p++; scontext = malloc(p - q); if (!scontext) { ERR(NULL, "out of memory"); free(buffer); fclose(fp); return -1; } r = scontext; s = q; while (*s) { if (!isspace(*s)) *r++ = *s; s++; } *r = 0; r = scontext; context_init(&context); if (mls_context_to_sid(policydb, oldc, &r, &context) < 0) { ERR(NULL, "invalid level %s (%s:%u)", scontext, path, lineno); free(scontext); continue; } free(scontext); memcpy(&usrdatum->dfltlevel, &context.range.level[0], sizeof(usrdatum->dfltlevel)); if (strncasecmp(p, "range", 5)) BADLINE(); p += 5; if (!isspace(*p)) BADLINE(); while (*p && isspace(*p)) p++; if (!(*p)) BADLINE(); q = p; while (*p && *p != ';') p++; if (!(*p)) BADLINE(); *p++ = 0; scontext = malloc(p - q); if (!scontext) { ERR(NULL, "out of memory"); free(buffer); fclose(fp); return -1; } r = scontext; s = q; while (*s) { if (!isspace(*s)) *r++ = *s; s++; } *r = 0; r = scontext; context_init(&context); if (mls_context_to_sid(policydb, oldc, &r, &context) < 0) { ERR(NULL, "invalid range %s (%s:%u)", scontext, path, lineno); free(scontext); continue; } free(scontext); memcpy(&usrdatum->range, &context.range, sizeof(usrdatum->range)); } } free(buffer); fclose(fp); return 0; } int sepol_genusers(void *data, size_t len, const char *usersdir, void **newdata, size_t * newlen) { struct policydb policydb; char path[PATH_MAX]; /* Construct policy database */ if (policydb_init(&policydb)) goto err; if (policydb_from_image(NULL, data, len, &policydb) < 0) goto err; /* Load locally defined users. */ snprintf(path, sizeof path, "%s/local.users", usersdir); if (load_users(&policydb, path) < 0) goto err_destroy; /* Write policy database */ if (policydb_to_image(NULL, &policydb, newdata, newlen) < 0) goto err_destroy; policydb_destroy(&policydb); return 0; err_destroy: policydb_destroy(&policydb); err: return -1; } int hidden sepol_genusers_policydb(policydb_t * policydb, const char *usersdir) { char path[PATH_MAX]; /* Load locally defined users. */ snprintf(path, sizeof path, "%s/local.users", usersdir); if (load_users(policydb, path) < 0) { ERR(NULL, "unable to load local.users: %s", strerror(errno)); return -1; } if (policydb_reindex_users(policydb) < 0) { ERR(NULL, "unable to reindex users: %s", strerror(errno)); return -1; } return 0; } /* -- End Deprecated -- */ libsepol-2.4/src/handle.c000066400000000000000000000023311246370572200153650ustar00rootroot00000000000000#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); } libsepol-2.4/src/handle.h000066400000000000000000000007301246370572200153730ustar00rootroot00000000000000#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 libsepol-2.4/src/hashtab.c000066400000000000000000000144641246370572200155560ustar00rootroot00000000000000 /* 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 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; unsigned int i; 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 *) malloc(sizeof(hashtab_ptr_t) * size); if (p->htable == NULL) { free(p); return NULL; } for (i = 0; i < size; i++) p->htable[i] = (hashtab_ptr_t) NULL; return p; } 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; 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; } int hashtab_replace(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum, void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { int hvalue; hashtab_ptr_t prev, cur, newnode; if (!h) return SEPOL_ENOMEM; hvalue = h->hash_value(h, key); prev = NULL; cur = h->htable[hvalue]; while (cur != NULL && h->keycmp(h, key, cur->key) > 0) { prev = cur; cur = cur->next; } if (cur && (h->keycmp(h, key, cur->key) == 0)) { if (destroy) destroy(cur->key, cur->datum, args); cur->key = key; cur->datum = datum; } else { 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; } } 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 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 hashtab_map(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { unsigned int i, ret; hashtab_ptr_t cur; 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_map_remove_on_error(hashtab_t h, int (*apply) (hashtab_key_t k, hashtab_datum_t d, void *args), void (*destroy) (hashtab_key_t k, hashtab_datum_t d, void *args), void *args) { unsigned int i; int ret; hashtab_ptr_t last, cur, temp; if (!h) return; for (i = 0; i < h->size; i++) { last = NULL; cur = h->htable[i]; while (cur != NULL) { ret = apply(cur->key, cur->datum, args); if (ret) { if (last) { last->next = cur->next; } else { h->htable[i] = cur->next; } temp = cur; cur = cur->next; if (destroy) destroy(temp->key, temp->datum, args); free(temp); h->nel--; } else { last = cur; cur = cur->next; } } } return; } 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); } libsepol-2.4/src/hierarchy.c000066400000000000000000000324361246370572200161210ustar00rootroot00000000000000/* 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" typedef struct hierarchy_args { policydb_t *p; avtab_t *expa; /* expanded avtab */ /* This tells check_avtab_hierarchy to check this list in addition to the unconditional avtab */ cond_av_list_t *opt_cond_list; sepol_handle_t *handle; int numerr; } hierarchy_args_t; /* * find_parent_(type|role|user) * * This function returns the parent datum of given XXX_datum_t * object or NULL, if it doesn't exist. * * If the given datum has a valid bounds, this function merely * returns the indicated object. Otherwise, it looks up the * parent based on the based hierarchy. */ #define find_parent_template(prefix) \ int find_parent_##prefix(hierarchy_args_t *a, \ prefix##_datum_t *datum, \ prefix##_datum_t **parent) \ { \ char *parent_name, *datum_name, *tmp; \ \ if (datum->bounds) \ *parent = a->p->prefix##_val_to_struct[datum->bounds - 1]; \ else { \ datum_name = a->p->p_##prefix##_val_to_name[datum->s.value - 1]; \ \ tmp = strrchr(datum_name, '.'); \ /* no '.' means it has no parent */ \ if (!tmp) { \ *parent = NULL; \ return 0; \ } \ \ parent_name = strdup(datum_name); \ if (!parent_name) \ return -1; \ parent_name[tmp - datum_name] = '\0'; \ \ *parent = hashtab_search(a->p->p_##prefix##s.table, parent_name); \ if (!*parent) { \ /* Orphan type/role/user */ \ ERR(a->handle, \ "%s doesn't exist, %s is an orphan", \ parent_name, \ a->p->p_##prefix##_val_to_name[datum->s.value - 1]); \ free(parent_name); \ return -1; \ } \ free(parent_name); \ } \ \ return 0; \ } static find_parent_template(type) static find_parent_template(role) static find_parent_template(user) static void compute_avtab_datum(hierarchy_args_t *args, avtab_key_t *key, avtab_datum_t *result) { avtab_datum_t *avdatp; uint32_t av = 0; avdatp = avtab_search(args->expa, key); if (avdatp) av = avdatp->data; if (args->opt_cond_list) { avdatp = cond_av_list_search(key, args->opt_cond_list); if (avdatp) av |= avdatp->data; } result->data = av; } /* This function verifies that the type passed in either has a parent or is in the * root of the namespace, 0 on success, 1 on orphan and -1 on error */ static int check_type_hierarchy_callback(hashtab_key_t k, hashtab_datum_t d, void *args) { hierarchy_args_t *a; type_datum_t *t, *tp; a = (hierarchy_args_t *) args; t = (type_datum_t *) d; if (t->flavor == TYPE_ATTRIB) { /* It's an attribute, we don't care */ return 0; } if (find_parent_type(a, t, &tp) < 0) return -1; if (tp && tp->flavor == TYPE_ATTRIB) { /* The parent is an attribute but the child isn't, not legal */ ERR(a->handle, "type %s is a child of an attribute %s", (char *) k, a->p->p_type_val_to_name[tp->s.value - 1]); a->numerr++; return -1; } return 0; } /* This function only verifies that the avtab node passed in does not violate any * hiearchy constraint via any relationship with other types in the avtab. * it should be called using avtab_map, returns 0 on success, 1 on violation and * -1 on error. opt_cond_list is an optional argument that tells this to check * a conditional list for the relationship as well as the unconditional avtab */ static int check_avtab_hierarchy_callback(avtab_key_t * k, avtab_datum_t * d, void *args) { avtab_key_t key; hierarchy_args_t *a = (hierarchy_args_t *) args; type_datum_t *s, *t1 = NULL, *t2 = NULL; avtab_datum_t av; if (!(k->specified & AVTAB_ALLOWED)) { /* This is not an allow rule, no checking done */ return 0; } /* search for parent first */ s = a->p->type_val_to_struct[k->source_type - 1]; if (find_parent_type(a, s, &t1) < 0) return -1; if (t1) { /* * search for access allowed between type 1's * parent and type 2. */ key.source_type = t1->s.value; key.target_type = k->target_type; key.target_class = k->target_class; key.specified = AVTAB_ALLOWED; compute_avtab_datum(a, &key, &av); if ((av.data & d->data) == d->data) return 0; } /* next we try type 1 and type 2's parent */ s = a->p->type_val_to_struct[k->target_type - 1]; if (find_parent_type(a, s, &t2) < 0) return -1; if (t2) { /* * search for access allowed between type 1 and * type 2's parent. */ key.source_type = k->source_type; key.target_type = t2->s.value; key.target_class = k->target_class; key.specified = AVTAB_ALLOWED; compute_avtab_datum(a, &key, &av); if ((av.data & d->data) == d->data) return 0; } if (t1 && t2) { /* * search for access allowed between type 1's parent * and type 2's parent. */ key.source_type = t1->s.value; key.target_type = t2->s.value; key.target_class = k->target_class; key.specified = AVTAB_ALLOWED; compute_avtab_datum(a, &key, &av); if ((av.data & d->data) == d->data) return 0; } /* * Neither one of these types have parents and * therefore the hierarchical constraint does not apply */ if (!t1 && !t2) return 0; /* * At this point there is a violation of the hierarchal * constraint, send error condition back */ ERR(a->handle, "hierarchy violation between types %s and %s : %s { %s }", a->p->p_type_val_to_name[k->source_type - 1], a->p->p_type_val_to_name[k->target_type - 1], a->p->p_class_val_to_name[k->target_class - 1], sepol_av_to_string(a->p, k->target_class, d->data & ~av.data)); a->numerr++; return 0; } /* * If same permissions are allowed for same combination of * source and target, we can evaluate them as unconditional * one. * See the following example. A_t type is bounds of B_t type, * so B_t can never have wider permissions then A_t. * A_t has conditional permission on X_t, however, a part of * them (getattr and read) are unconditionaly allowed to A_t. * * Example) * typebounds A_t B_t; * * allow B_t X_t : file { getattr }; * if (foo_bool) { * allow A_t X_t : file { getattr read }; * } else { * allow A_t X_t : file { getattr read write }; * } * * We have to pull up them as unconditional ones in this case, * because it seems to us B_t is violated to bounds constraints * during unconditional policy checking. */ static int pullup_unconditional_perms(cond_list_t * cond_list, hierarchy_args_t * args) { cond_list_t *cur_node; cond_av_list_t *cur_av, *expl_true = NULL, *expl_false = NULL; avtab_t expa_true, expa_false; avtab_datum_t *avdatp; avtab_datum_t avdat; avtab_ptr_t avnode; for (cur_node = cond_list; cur_node; cur_node = cur_node->next) { if (avtab_init(&expa_true)) goto oom0; if (avtab_init(&expa_false)) goto oom1; if (expand_cond_av_list(args->p, cur_node->true_list, &expl_true, &expa_true)) goto oom2; if (expand_cond_av_list(args->p, cur_node->false_list, &expl_false, &expa_false)) goto oom3; for (cur_av = expl_true; cur_av; cur_av = cur_av->next) { avdatp = avtab_search(&expa_false, &cur_av->node->key); if (!avdatp) continue; avdat.data = (cur_av->node->datum.data & avdatp->data); if (!avdat.data) continue; avnode = avtab_search_node(args->expa, &cur_av->node->key); if (avnode) { avnode->datum.data |= avdat.data; } else { if (avtab_insert(args->expa, &cur_av->node->key, &avdat)) goto oom4; } } cond_av_list_destroy(expl_false); cond_av_list_destroy(expl_true); avtab_destroy(&expa_false); avtab_destroy(&expa_true); } return 0; oom4: cond_av_list_destroy(expl_false); oom3: cond_av_list_destroy(expl_true); oom2: avtab_destroy(&expa_false); oom1: avtab_destroy(&expa_true); oom0: ERR(args->handle, "out of memory on conditional av list expansion"); return 1; } static int check_cond_avtab_hierarchy(cond_list_t * cond_list, hierarchy_args_t * args) { int rc; cond_list_t *cur_node; cond_av_list_t *cur_av, *expl = NULL; avtab_t expa; hierarchy_args_t *a = (hierarchy_args_t *) args; avtab_datum_t avdat, *uncond; for (cur_node = cond_list; cur_node; cur_node = cur_node->next) { /* * Check true condition */ if (avtab_init(&expa)) goto oom; if (expand_cond_av_list(args->p, cur_node->true_list, &expl, &expa)) { avtab_destroy(&expa); goto oom; } args->opt_cond_list = expl; for (cur_av = expl; cur_av; cur_av = cur_av->next) { avdat.data = cur_av->node->datum.data; uncond = avtab_search(a->expa, &cur_av->node->key); if (uncond) avdat.data |= uncond->data; rc = check_avtab_hierarchy_callback(&cur_av->node->key, &avdat, args); if (rc) args->numerr++; } cond_av_list_destroy(expl); avtab_destroy(&expa); /* * Check false condition */ if (avtab_init(&expa)) goto oom; if (expand_cond_av_list(args->p, cur_node->false_list, &expl, &expa)) { avtab_destroy(&expa); goto oom; } args->opt_cond_list = expl; for (cur_av = expl; cur_av; cur_av = cur_av->next) { avdat.data = cur_av->node->datum.data; uncond = avtab_search(a->expa, &cur_av->node->key); if (uncond) avdat.data |= uncond->data; rc = check_avtab_hierarchy_callback(&cur_av->node->key, &avdat, args); if (rc) a->numerr++; } cond_av_list_destroy(expl); avtab_destroy(&expa); } return 0; oom: ERR(args->handle, "out of memory on conditional av list expansion"); return 1; } /* The role hierarchy is defined as: a child role cannot have more types than it's parent. * This function should be called with hashtab_map, it will return 0 on success, 1 on * constraint violation and -1 on error */ static int check_role_hierarchy_callback(hashtab_key_t k __attribute__ ((unused)), hashtab_datum_t d, void *args) { hierarchy_args_t *a; role_datum_t *r, *rp; a = (hierarchy_args_t *) args; r = (role_datum_t *) d; if (find_parent_role(a, r, &rp) < 0) return -1; if (rp && !ebitmap_contains(&rp->types.types, &r->types.types)) { /* hierarchical constraint violation, return error */ ERR(a->handle, "Role hierarchy violation, %s exceeds %s", (char *) k, a->p->p_role_val_to_name[rp->s.value - 1]); a->numerr++; } return 0; } /* The user hierarchy is defined as: a child user cannot have a role that * its parent doesn't have. This function should be called with hashtab_map, * it will return 0 on success, 1 on constraint violation and -1 on error. */ static int check_user_hierarchy_callback(hashtab_key_t k __attribute__ ((unused)), hashtab_datum_t d, void *args) { hierarchy_args_t *a; user_datum_t *u, *up; a = (hierarchy_args_t *) args; u = (user_datum_t *) d; if (find_parent_user(a, u, &up) < 0) return -1; if (up && !ebitmap_contains(&up->roles.roles, &u->roles.roles)) { /* hierarchical constraint violation, return error */ ERR(a->handle, "User hierarchy violation, %s exceeds %s", (char *) k, a->p->p_user_val_to_name[up->s.value - 1]); a->numerr++; } return 0; } int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p) { hierarchy_args_t args; avtab_t expa; if (avtab_init(&expa)) goto oom; if (expand_avtab(p, &p->te_avtab, &expa)) { avtab_destroy(&expa); goto oom; } args.p = p; args.expa = &expa; args.opt_cond_list = NULL; args.handle = handle; args.numerr = 0; if (hashtab_map(p->p_types.table, check_type_hierarchy_callback, &args)) goto bad; if (pullup_unconditional_perms(p->cond_list, &args)) return -1; if (avtab_map(&expa, check_avtab_hierarchy_callback, &args)) goto bad; if (check_cond_avtab_hierarchy(p->cond_list, &args)) goto bad; if (hashtab_map(p->p_roles.table, check_role_hierarchy_callback, &args)) goto bad; if (hashtab_map(p->p_users.table, check_user_hierarchy_callback, &args)) goto bad; if (args.numerr) { ERR(handle, "%d total errors found during hierarchy check", args.numerr); goto bad; } avtab_destroy(&expa); return 0; bad: avtab_destroy(&expa); return -1; oom: ERR(handle, "Out of memory"); return -1; } libsepol-2.4/src/iface_internal.h000066400000000000000000000010401246370572200170760ustar00rootroot00000000000000#ifndef _SEPOL_IFACE_INTERNAL_H_ #define _SEPOL_IFACE_INTERNAL_H_ #include #include #include "dso.h" hidden_proto(sepol_iface_create) hidden_proto(sepol_iface_free) hidden_proto(sepol_iface_get_ifcon) hidden_proto(sepol_iface_get_msgcon) hidden_proto(sepol_iface_get_name) hidden_proto(sepol_iface_key_create) hidden_proto(sepol_iface_key_unpack) hidden_proto(sepol_iface_set_ifcon) hidden_proto(sepol_iface_set_msgcon) hidden_proto(sepol_iface_set_name) #endif libsepol-2.4/src/iface_record.c000066400000000000000000000110071246370572200165370ustar00rootroot00000000000000#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 */ const 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 = name; *key_ptr = tmp_key; return STATUS_SUCCESS; } hidden_def(sepol_iface_key_create) void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name) { *name = key->name; } hidden_def(sepol_iface_key_unpack) 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) { 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; } hidden_def(sepol_iface_create) /* Name */ const char *sepol_iface_get_name(const sepol_iface_t * iface) { return iface->name; } hidden_def(sepol_iface_get_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; } hidden_def(sepol_iface_set_name) /* Interface Context */ sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface) { return iface->netif_con; } hidden_def(sepol_iface_get_ifcon) 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; } hidden_def(sepol_iface_set_ifcon) /* Message Context */ sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface) { return iface->netmsg_con; } hidden_def(sepol_iface_get_msgcon) 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; } hidden_def(sepol_iface_set_msgcon) /* 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); } hidden_def(sepol_iface_free) libsepol-2.4/src/interfaces.c000066400000000000000000000137321246370572200162640ustar00rootroot00000000000000#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; handle = NULL; 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; handle = NULL; 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; } libsepol-2.4/src/libsepol.map.in000066400000000000000000000016761246370572200167160ustar00rootroot00000000000000{ global: expand_module_avrules; sepol_module_package_*; sepol_link_modules; sepol_expand_module; sepol_link_packages; sepol_bool_*; sepol_genbools*; sepol_context_*; sepol_mls_*; sepol_check_context; sepol_iface_*; sepol_port_*; sepol_node_*; sepol_user_*; sepol_genusers; sepol_set_delusers; sepol_msg_*; sepol_debug; sepol_handle_*; sepol_policydb_*; sepol_set_policydb_from_file; sepol_policy_kern_*; sepol_policy_file_*; sepol_get_disable_dontaudit; sepol_set_disable_dontaudit; sepol_set_expand_consume_base; sepol_get_preserve_tunables; sepol_set_preserve_tunables; cil_db_init; cil_set_disable_dontaudit; cil_set_disable_neverallow; cil_set_preserve_tunables; cil_set_handle_unknown; cil_db_destroy; cil_add_file; cil_compile; cil_build_policydb; cil_userprefixes_to_string; cil_selinuxusers_to_string; cil_filecons_to_string; cil_set_log_level; cil_set_log_handler; cil_set_malloc_error_handler; local: *; }; libsepol-2.4/src/libsepol.pc.in000066400000000000000000000004001246370572200165230ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=${prefix} libdir=${exec_prefix}/@libdir@ includedir=@includedir@ Name: libsepol Description: SELinux policy library Version: @VERSION@ URL: http://userspace.selinuxproject.org/ Libs: -L${libdir} -lsepol Cflags: -I${includedir} libsepol-2.4/src/link.c000066400000000000000000002136761246370572200151070ustar00rootroot00000000000000/* 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" #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 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 dependancy 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 *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\n"); 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; } 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\n"); ret = SEPOL_ERR; goto err; } if (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\n"); 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 = 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; } /* permissive should pass to the base type */ base_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); } 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; } 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!"); 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\n", 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\n", 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 & TYPE_FLAGS_PERMISSIVE); 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 & TYPE_FLAGS_PERMISSIVE); } /* 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_bit(&types->types, tnode, i) { if (ebitmap_node_get_bit(tnode, i)) { assert(mod->map[SYM_TYPES][i]); if (ebitmap_set_bit (&dst->types, mod->map[SYM_TYPES][i] - 1, 1)) { goto cleanup; } } } ebitmap_for_each_bit(&types->negset, tnode, i) { if (ebitmap_node_get_bit(tnode, i)) { assert(mod->map[SYM_TYPES][i]); if (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_bit(&roles->roles, rnode, i) { if (ebitmap_node_get_bit(rnode, i)) { assert(mod->map[SYM_ROLES][i]); if (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; ebitmap_destroy(&tmp); return 0; cleanup: ERR(state->handle, "Out of memory!"); 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_bit(&role->dominates, rnode, i) { if (ebitmap_node_get_bit(rnode, i)) { assert(mod->map[SYM_ROLES][i]); if (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; } ebitmap_destroy(&e_tmp); if (role->flavor == ROLE_ATTRIB) { ebitmap_init(&e_tmp); ebitmap_for_each_bit(&role->roles, rnode, i) { if (ebitmap_node_get_bit(rnode, i)) { assert(mod->map[SYM_ROLES][i]); if (ebitmap_set_bit (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { goto cleanup; } } } if (ebitmap_union(&dest_role->roles, &e_tmp)) { goto cleanup; } ebitmap_destroy(&e_tmp); } return 0; cleanup: ERR(state->handle, "Out of memory!"); 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_bit(&type->types, tnode, i) { if (ebitmap_node_get_bit(tnode, i)) { assert(mod->map[SYM_TYPES][i]); if (ebitmap_set_bit (&e_tmp, mod->map[SYM_TYPES][i] - 1, 1)) { goto cleanup; } } } if (ebitmap_union(&new_type->types, &e_tmp)) { goto cleanup; } ebitmap_destroy(&e_tmp); return 0; cleanup: ERR(state->handle, "Out of memory!"); 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 & (1U << i))) continue; new_perm->data |= (1U << (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; } 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_bit(&cur->classes, cnode, i) { if (ebitmap_node_get_bit(cnode, i)) { assert(module->map[SYM_CLASSES][i]); if (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]; 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_bit(&rule->tclasses, cnode, i) { if (ebitmap_node_get_bit(cnode, i)) { assert(mod->map[SYM_CLASSES][i]); if (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 = hashtab_map(src_symtab[i].table, copy_callback_f[i], state); if (ret) { return ret; } } } if (hashtab_map(src_symtab[SYM_TYPES].table, type_bounds_copy_callback, state)) return -1; if (hashtab_map(src_symtab[SYM_TYPES].table, alias_copy_callback, state)) return -1; if (hashtab_map(src_symtab[SYM_ROLES].table, role_bounds_copy_callback, state)) return -1; if (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 && 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_bit(srcmap, node, j) { if (ebitmap_node_get_bit(node, j)) { assert(module->map[i][j] != 0); if (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 = malloc(largest_mapped_class_value * sizeof(*dest->class_perms_map))) == NULL) { goto cleanup; } for (i = 0; i < largest_mapped_class_value; i++) { ebitmap_init(dest->class_perms_map + i); } 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_bit(srcmap, node, j) { if (ebitmap_node_get_bit(node, j) && 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\n"); 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 (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_bit(bitmap, node, j) { if (!ebitmap_node_get_bit(node, j)) { continue; } /* 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_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; if (!ebitmap_node_get_bit(node, j)) { continue; } 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)hashtab_map(cladatum->permissions.table, find_perm, &fparg); if (fparg.key == NULL && cladatum->comdatum != NULL) { rc = 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)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)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 * cicular. 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\n", 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_bit(&role->roles, rnode, i) { if (ebitmap_node_get_bit(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 (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 (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 ((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 all types, declared and required */ for (i = 0; i < len; i++) { state.cur = modules[i]; state.cur_mod_name = modules[i]->policy->name; ret = hashtab_map(modules[i]->policy->p_types.table, type_copy_callback, &state); if (ret) { retval = ret; goto cleanup; } } /* then copy everything else, including aliases, and fixup attributes */ for (i = 0; i < len; i++) { state.cur = modules[i]; state.cur_mod_name = modules[i]->policy->name; ret = copy_identifiers(&state, modules[i]->policy->symtab, NULL); if (ret) { retval = ret; goto cleanup; } } if (policydb_index_others(state.handle, state.base, 0)) { ERR(state.handle, "Error while indexing others"); 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 (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; } libsepol-2.4/src/mls.c000066400000000000000000000434471246370572200147420ustar00rootroot00000000000000/* 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 = 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; 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 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 (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 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 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 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; 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; levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, p-> p_sens_val_to_name [c->range.level[l]. sens - 1]); if (!levdatum) return 0; ebitmap_for_each_bit(&c->range.level[l].cat, cnode, i) { if (ebitmap_node_get_bit(cnode, i)) { if (i > p->p_cats.nprim) return 0; if (!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 (!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 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 (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 (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, 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 = 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, 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 = 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, 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 = ebitmap_cpy(&context->range.level[l].cat, &range->level[l].cat); if (rc) break; } return rc; } int 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 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_bit(&c->range.level[l].cat, cnode, i) { if (ebitmap_node_get_bit(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 = ebitmap_set_bit(&bitmap, catdatum->s.value - 1, 1); if (rc) return rc; } } ebitmap_destroy(&c->range.level[l].cat); c->range.level[l].cat = bitmap; } return 0; } int mls_compute_sid(policydb_t * policydb, context_struct_t * scontext, context_struct_t * tcontext, sepol_security_class_t tclass, uint32_t specified, context_struct_t * newcontext) { range_trans_t *rtr; if (!policydb->mls) return 0; switch (specified) { case AVTAB_TRANSITION: /* Look for a range transition rule. */ for (rtr = policydb->range_tr; rtr; rtr = rtr->next) { if (rtr->source_type == scontext->type && rtr->target_type == tcontext->type && rtr->target_class == tclass) { /* Set the range from the rule */ return mls_range_set(newcontext, &rtr->target_range); } } /* Fallthrough */ case AVTAB_CHANGE: if (tclass == SECCLASS_PROCESS) /* 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: /* Only polyinstantiate the MLS attributes if the type is being polyinstantiated */ if (newcontext->type != tcontext->type) { /* Use the process effective MLS attributes. */ return mls_scopy_context(newcontext, scontext); } else { /* Use the related object MLS attributes. */ return mls_copy_context(newcontext, tcontext); } default: return -EINVAL; } return -EINVAL; } int sepol_mls_contains(sepol_handle_t * handle, 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 (mls_from_string(handle, &policydb->p, mls1, ctx1) < 0) goto err; if (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, 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 = 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, mls_semantic_level_t * src) { mls_semantic_cat_t *cat, *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, 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; } libsepol-2.4/src/mls.h000066400000000000000000000045211246370572200147350ustar00rootroot00000000000000/* 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 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 mls_compute_context_len(const policydb_t * policydb, const context_struct_t * context); /* Deprecated */ extern void mls_sid_to_context(const policydb_t * policydb, const context_struct_t * context, char **scontext); /* Deprecated */ extern int mls_context_to_sid(const policydb_t * policydb, char oldc, char **scontext, context_struct_t * context); extern int mls_context_isvalid(const policydb_t * p, const context_struct_t * c); extern int mls_convert_context(policydb_t * oldp, policydb_t * newp, context_struct_t * context); extern int mls_compute_sid(policydb_t * policydb, context_struct_t * scontext, context_struct_t * tcontext, sepol_security_class_t tclass, uint32_t specified, context_struct_t * newcontext); extern int mls_setup_user_range(context_struct_t * fromcon, user_datum_t * user, context_struct_t * usercon, int mls); #endif libsepol-2.4/src/module.c000066400000000000000000000573221246370572200154310ustar00rootroot00000000000000/* 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 #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 (offset > LONG_MAX) { errno = EFAULT; return -1; } return fseek(fp->fp, (long)offset, SEEK_SET); 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: 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; 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); return rc; } hidden_def(sepol_module_package_create) /* 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); } hidden_def(sepol_module_package_free) 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++) { 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; } /* 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 *) malloc((nsec + 1) * sizeof(size_t)); if (!off) { ERR(file->handle, "out of memory"); goto err; } free(buf); buf = malloc(sizeof(uint32_t) * nsec); 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 = 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: %ux ", 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]); *name = malloc(len + 1); if (!*name) { ERR(file->handle, "out of memory"); goto cleanup; } rc = next_entry(*name, file, len); if (rc < 0) { ERR(file->handle, "cannot get module name string (at section %u)", i); goto cleanup; } (*name)[len] = '\0'; 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]); *version = malloc(len + 1); if (!*version) { ERR(file->handle, "out of memory"); goto cleanup; } rc = next_entry(*version, file, len); if (rc < 0) { ERR(file->handle, "cannot get module version string (at section %u)", i); goto cleanup; } (*version)[len] = '\0'; 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 (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 (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); } libsepol-2.4/src/module_internal.h000066400000000000000000000002021246370572200173130ustar00rootroot00000000000000#include #include "dso.h" hidden_proto(sepol_module_package_create) hidden_proto(sepol_module_package_free) libsepol-2.4/src/node_internal.h000066400000000000000000000015251246370572200167640ustar00rootroot00000000000000#ifndef _SEPOL_NODE_INTERNAL_H_ #define _SEPOL_NODE_INTERNAL_H_ #include #include #include "dso.h" hidden_proto(sepol_node_create) hidden_proto(sepol_node_key_free) hidden_proto(sepol_node_free) hidden_proto(sepol_node_get_con) hidden_proto(sepol_node_get_addr) hidden_proto(sepol_node_get_addr_bytes) hidden_proto(sepol_node_get_mask) hidden_proto(sepol_node_get_mask_bytes) hidden_proto(sepol_node_get_proto) hidden_proto(sepol_node_get_proto_str) hidden_proto(sepol_node_key_create) hidden_proto(sepol_node_key_unpack) hidden_proto(sepol_node_set_con) hidden_proto(sepol_node_set_addr) hidden_proto(sepol_node_set_addr_bytes) hidden_proto(sepol_node_set_mask) hidden_proto(sepol_node_set_mask_bytes) hidden_proto(sepol_node_set_proto) #endif libsepol-2.4/src/node_record.c000066400000000000000000000324571246370572200164310ustar00rootroot00000000000000#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: %s", addr_str, strerror(errno)); 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: %s", addr_str, strerror(errno)); return STATUS_ERR; } #ifdef DARWIN memcpy(addr_bytes, in_addr.s6_addr, 16); #else memcpy(addr_bytes, in_addr.s6_addr32, 16); #endif 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 the 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: %s", strerror(errno)); return STATUS_ERR; } break; } case SEPOL_PROTO_IP6: { struct in6_addr addr; memset(&addr, 0, sizeof(struct in6_addr)); #ifdef DARWIN memcpy(&addr.s6_addr[0], addr_bytes, 16); #else memcpy(&addr.s6_addr32[0], addr_bytes, 16); #endif if (inet_ntop(AF_INET6, &addr, addr_str, INET6_ADDRSTRLEN) == NULL) { ERR(handle, "could not expand IPv6 address to string: %s", strerror(errno)); 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; } hidden_def(sepol_node_key_create) 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; } hidden_def(sepol_node_key_unpack) 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); } hidden_def(sepol_node_key_free) 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; } hidden_def(sepol_node_get_addr) 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; } hidden_def(sepol_node_get_addr_bytes) 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; } hidden_def(sepol_node_set_addr) 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; } hidden_def(sepol_node_set_addr_bytes) /* 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; } hidden_def(sepol_node_get_mask) 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; } hidden_def(sepol_node_get_mask_bytes) 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; } hidden_def(sepol_node_set_mask) 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; } hidden_def(sepol_node_set_mask_bytes) /* Protocol */ int sepol_node_get_proto(const sepol_node_t * node) { return node->proto; } hidden_def(sepol_node_get_proto) void sepol_node_set_proto(sepol_node_t * node, int proto) { node->proto = proto; } hidden_def(sepol_node_set_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 "???"; } } hidden_def(sepol_node_get_proto_str) /* 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; } hidden_def(sepol_node_create) /* 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); } hidden_def(sepol_node_free) /* Context */ sepol_context_t *sepol_node_get_con(const sepol_node_t * node) { return node->con; } hidden_def(sepol_node_get_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; } hidden_def(sepol_node_set_con) libsepol-2.4/src/nodes.c000066400000000000000000000207231246370572200152470ustar00rootroot00000000000000#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; tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t)); if (!tmp_node) goto omem; size_t addr_bsize, mask_bsize; /* 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; int 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; handle = NULL; 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; } } 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; } libsepol-2.4/src/polcaps.c000066400000000000000000000014251246370572200155760ustar00rootroot00000000000000/* * Policy capability support functions */ #include #include static const char *polcap_names[] = { "network_peer_controls", /* POLICYDB_CAPABILITY_NETPEER */ "open_perms", /* POLICYDB_CAPABILITY_OPENPERM */ "redhat1", /* POLICYDB_CAPABILITY_REDHAT1, aka ptrace_child */ "always_check_network", /* POLICYDB_CAPABILITY_ALWAYSNETWORK */ NULL }; int sepol_polcap_getnum(const char *name) { int capnum; for (capnum = 0; capnum <= POLICYDB_CAPABILITY_MAX; capnum++) { if (polcap_names[capnum] == NULL) continue; if (strcasecmp(polcap_names[capnum], name) == 0) return capnum; } return -1; } const char *sepol_polcap_getname(int capnum) { if (capnum > POLICYDB_CAPABILITY_MAX) return NULL; return polcap_names[capnum]; } libsepol-2.4/src/policydb.c000066400000000000000000002555421246370572200157550ustar00rootroot00000000000000 /* 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. * * 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 #include "private.h" #include "debug.h" #include "mls.h" #define POLICYDB_TARGET_SZ ARRAY_SIZE(policydb_target_strings) const char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING }; /* These need to be updated if SYM_NUM or OCON_NUM changes */ static 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_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_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_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, }, }; #if 0 static char *symtab_name[SYM_NUM] = { "common prefixes", "classes", "roles", "types", "users", "bools" mls_symtab_names cond_symtab_names }; #endif static unsigned int symtab_sizes[SYM_NUM] = { 2, 32, 16, 512, 128, 16, 16, 16, }; struct policydb_compat_info *policydb_lookup_compat(unsigned int version, unsigned int type, unsigned int target_platform) { unsigned int i; 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) { ebitmap_destroy(&x->types); 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) { 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) { ebitmap_destroy(&x->dominates); type_set_destroy(&x->types); ebitmap_destroy(&x->cache); 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) { 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); 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); } } 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); } void role_trans_rule_destroy(role_trans_rule_t * x) { if (x != NULL) { role_set_destroy(&x->roles); type_set_destroy(&x->types); 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); 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 = 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; } /* * Initialize a policy database structure. */ int policydb_init(policydb_t * p) { int i, rc; memset(p, 0, sizeof(policydb_t)); ebitmap_init(&p->policycaps); ebitmap_init(&p->permissive_map); for (i = 0; i < SYM_NUM; i++) { p->sym_val_to_name[i] = NULL; rc = symtab_init(&p->symtab[i], symtab_sizes[i]); if (rc) goto out_free_symtab; } /* initialize the module stuff */ for (i = 0; i < SYM_NUM; i++) { if (symtab_init(&p->scope[i], symtab_sizes[i])) { goto out_free_symtab; } } if ((p->global = avrule_block_create()) == NULL || (p->global->branch_list = avrule_decl_create(1)) == NULL) { goto out_free_symtab; } p->decl_val_to_struct = NULL; rc = avtab_init(&p->te_avtab); if (rc) goto out_free_symtab; rc = roles_init(p); if (rc) goto out_free_symtab; rc = cond_policydb_init(p); if (rc) goto out_free_symtab; out: return rc; out_free_symtab: for (i = 0; i < SYM_NUM; i++) { hashtab_destroy(p->symtab[i].table); hashtab_destroy(p->scope[i].table); } avrule_block_list_destroy(p->global); goto out; } 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; 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; 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 (!comdatum->s.value || comdatum->s.value > p->p_commons.nprim) 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 (!cladatum->s.value || cladatum->s.value > p->p_classes.nprim) 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 (!role->s.value || role->s.value > p->p_roles.nprim) 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 (!typdatum->s.value || typdatum->s.value > p->p_types.nprim) 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 (!usrdatum->s.value || usrdatum->s.value > p->p_users.nprim) 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 (!levdatum->level->sens || levdatum->level->sens > p->p_levels.nprim) 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 (!catdatum->s.value || catdatum->s.value > p->p_cats.nprim) 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, 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 **) malloc(p->p_commons.nprim * sizeof(char *)); if (!p->p_common_val_to_name) return -1; if (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 **) malloc(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 **) malloc(p->p_classes.nprim * sizeof(char *)); if (!p->p_class_val_to_name) return -1; if (hashtab_map(p->p_classes.table, class_index, p)) return -1; return 0; } int policydb_index_bools(policydb_t * p) { if (cond_init_bool_indexes(p) == -1) return -1; p->p_bool_val_to_name = (char **) malloc(p->p_bools.nprim * sizeof(char *)); if (!p->p_bool_val_to_name) return -1; if (hashtab_map(p->p_bools.table, cond_index_bool, p)) return -1; return 0; } int policydb_index_decls(policydb_t * p) { avrule_block_t *curblock; avrule_decl_t *decl; 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) { 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 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 **) malloc(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 **) malloc(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; cond_init_bool_indexes(p); 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 (hashtab_map(p->symtab[i].table, index_f[i], p)) return -1; } } /* This pre-expands the roles and users for context validity checking */ if (hashtab_map(p->p_roles.table, policydb_role_cache, p)) return -1; if (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)hashtab_map(comdatum->permissions.table, perm_destroy, 0); 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; constraint_expr_t *e, *etmp; if (key) free(key); cladatum = (class_datum_t *) datum; if (cladatum == NULL) { return 0; } (void)hashtab_map(cladatum->permissions.table, perm_destroy, 0); hashtab_destroy(cladatum->permissions.table); constraint = cladatum->constraints; while (constraint) { e = constraint->expr; while (e) { etmp = e; e = e->next; constraint_expr_destroy(etmp); } ctemp = constraint; constraint = constraint->next; free(ctemp); } constraint = cladatum->validatetrans; while (constraint) { e = constraint->expr; while (e) { etmp = e; e = e->next; constraint_expr_destroy(etmp); } 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, cond_destroy_bool, sens_destroy, cat_destroy,}; 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); free(ctmp); } } } 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) free(ctmp->u.name); free(ctmp); } } } /* * Free any memory allocated by a policy database structure. */ void 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; range_trans_t *rt, *lrt = NULL; filename_trans_t *ft, *nft; if (!p) return; ebitmap_destroy(&p->policycaps); 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)hashtab_map(p->scope[i].table, scope_destroy, 0); hashtab_destroy(p->scope[i].table); } avrule_block_list_destroy(p->global); free(p->name); free(p->version); 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); } cond_policydb_destroy(p); for (tr = p->role_tr; tr; tr = tr->next) { if (ltr) free(ltr); ltr = tr; } if (ltr) free(ltr); ft = p->filename_trans; while (ft) { nft = ft->next; free(ft->name); free(ft); ft = nft; } for (ra = p->role_allow; ra; ra = ra->next) { if (lra) free(lra); lra = ra; } if (lra) free(lra); for (rt = p->range_tr; rt; rt = rt->next) { if (lrt) { ebitmap_destroy(&lrt->target_range.level[0].cat); ebitmap_destroy(&lrt->target_range.level[1].cat); free(lrt); } lrt = rt; } if (lrt) { ebitmap_destroy(&lrt->target_range.level[0].cat); ebitmap_destroy(&lrt->target_range.level[1].cat); free(lrt); } if (p->type_attr_map) { for (i = 0; i < p->p_types.nprim; i++) { 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++) { 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)hashtab_map(symtab[i].table, destroy_f[i], 0); 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; } hashtab_destroy_func_t get_symtab_destroy_func(int sym_num) { if (sym_num < 0 || sym_num >= SYM_NUM) { return NULL; } return (hashtab_destroy_func_t) destroy_f[sym_num]; } /* * Load the initial SIDs specified in a policy database * structure into a SID table. */ int 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 (!c->context[0].user) { ERR(NULL, "SID %s was never defined", c->u.name); return -1; } 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 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; } else if (scope_datum->scope != scope) { /* This only happens in DECL then REQUIRE case, which is handled by caller */ return -2; } /* 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; } return retval; } int type_set_or(type_set_t * dst, type_set_t * a, 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, type_set_t * src) { type_set_init(dst); dst->flags = src->flags; if (ebitmap_cpy(&dst->types, &src->types)) return -1; if (ebitmap_cpy(&dst->negset, &src->negset)) return -1; return 0; } int type_set_or_eq(type_set_t * dst, 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; } int role_set_get_role(role_set_t * x, uint32_t role) { if (x->flags & ROLE_STAR) return 1; if (ebitmap_get_bit(&x->roles, role - 1)) { if (x->flags & ROLE_COMP) return 0; else return 1; } else { if (x->flags & ROLE_COMP) return 1; else return 0; } } /***********************************************************************/ /* 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 (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 (ebitmap_read(&t->types, fp)) return -1; if (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 = ebitmap_read(&r->level[0].cat, fp); if (rc) { ERR(fp->handle, "error reading low categories"); goto out; } if (items > 1) { rc = ebitmap_read(&r->level[1].cat, fp); if (rc) { ERR(fp->handle, "error reading high categories"); goto bad_high; } } else { rc = 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: 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 (!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) { 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]); perdatum->s.value = 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; 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]); comdatum->s.value = le32_to_cpu(buf[1]); if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) goto bad; comdatum->permissions.nprim = le32_to_cpu(buf[2]); 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)) 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 (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]); len2 = le32_to_cpu(buf[1]); cladatum->s.value = le32_to_cpu(buf[2]); if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) goto bad; cladatum->permissions.nprim = le32_to_cpu(buf[3]); 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)) 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 __attribute__ ((unused)), 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]); 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 (ebitmap_read(&role->dominates, fp)) goto bad; if (p->policy_type == POLICY_KERN) { if (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 (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 __attribute__ ((unused)), 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]); 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 (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; } 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 = SECCLASS_PROCESS; ltr = tr; } return 0; } 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 filename_trans_read(filename_trans_t **t, struct policy_file *fp) { unsigned int i; uint32_t buf[4], nel, len; filename_trans_t *ft, *lft; int rc; char *name; rc = next_entry(buf, fp, sizeof(uint32_t)); if (rc < 0) return -1; nel = le32_to_cpu(buf[0]); lft = NULL; for (i = 0; i < nel; i++) { ft = calloc(1, sizeof(struct filename_trans)); if (!ft) return -1; if (lft) lft->next = ft; else *t = ft; lft = ft; rc = next_entry(buf, fp, sizeof(uint32_t)); if (rc < 0) return -1; len = le32_to_cpu(buf[0]); name = calloc(len + 1, sizeof(*name)); if (!name) return -1; ft->name = name; rc = next_entry(name, fp, len); if (rc < 0) return -1; rc = next_entry(buf, fp, sizeof(uint32_t) * 4); if (rc < 0) return -1; ft->stype = le32_to_cpu(buf[0]); ft->ttype = le32_to_cpu(buf[1]); ft->tclass = le32_to_cpu(buf[2]); ft->otype = le32_to_cpu(buf[3]); } return 0; } static int ocontext_read_xen(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { unsigned int i, j; size_t nel; 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 (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: 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; default: /* should never get here */ ERR(fp->handle, "Unknown Xen ocontext"); return -1; } } } return 0; } static int ocontext_read_selinux(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 (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]); 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_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]); 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(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; unsigned int 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]); 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]); 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; } } 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 (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]); 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 (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]); 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]); 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, cond_read_bool, sens_read, cat_read,}; /************** module reading functions below **************/ static avrule_t *avrule_read(policydb_t * p __attribute__ ((unused)), 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; } 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, *lrt; range_trans_rule_t *rtr, *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]); lrt = NULL; for (i = 0; i < nel; i++) { rt = calloc(1, sizeof(range_trans_t)); if (!rt) return -1; if (lrt) lrt->next = rt; else p->range_tr = rt; rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); if (rc < 0) return -1; rt->source_type = le32_to_cpu(buf[0]); rt->target_type = le32_to_cpu(buf[1]); if (new_rangetr) { rc = next_entry(buf, fp, (sizeof(uint32_t))); if (rc < 0) return -1; rt->target_class = le32_to_cpu(buf[0]); } else rt->target_class = SECCLASS_PROCESS; if (mls_read_range_helper(&rt->target_range, fp)) return -1; lrt = rt; } /* if this is a kernel policy, we are done - otherwise we need to * convert these structs to range_trans_rule_ts */ if (p->policy_type == POLICY_KERN) return 0; /* create range_trans_rules_ts that correspond to the range_trans_ts * that were just read in from an older policy */ for (rt = p->range_tr; rt; rt = rt->next) { rtr = malloc(sizeof(range_trans_rule_t)); if (!rtr) { return -1; } range_trans_rule_init(rtr); if (lrtr) lrtr->next = rtr; else p->global->enabled->range_tr_rules = rtr; if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1)) return -1; if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1)) return -1; if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1)) return -1; if (mls_range_to_semantic(&rt->target_range, &rtr->trange)) return -1; lrtr = rtr; } /* now destroy the range_trans_ts */ lrt = NULL; for (rt = p->range_tr; rt; rt = rt->next) { if (lrt) { ebitmap_destroy(&lrt->target_range.level[0].cat); ebitmap_destroy(&lrt->target_range.level[1].cat); free(lrt); } lrt = rt; } if (lrt) { ebitmap_destroy(&lrt->target_range.level[0].cat); ebitmap_destroy(&lrt->target_range.level[1].cat); free(lrt); } p->range_tr = NULL; return 0; } 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 (ebitmap_read(&tr->classes, fp)) return -1; } else { if (ebitmap_set_bit(&tr->classes, SECCLASS_PROCESS - 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(filename_trans_rule_t ** r, struct policy_file *fp) { uint32_t buf[2], nel; unsigned int i, len; 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]); 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; rc = next_entry(buf, fp, sizeof(uint32_t) * 2); if (rc < 0) return -1; ftr->tclass = le32_to_cpu(buf[0]); ftr->otype = le32_to_cpu(buf[1]); } 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 (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 (ebitmap_read(scope_index->scope + i, fp) == -1) { 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 (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 (ebitmap_read(scope_index->class_perms_map + i, fp) == -1) { 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 (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(&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]); 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]); 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]); assert(scope->decl_ids_len > 0); if ((scope->decl_ids = malloc(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; } /* * Read the configuration data from a policy database binary * representation file into a policy database structure. */ int 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; 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 > POLICYDB_STRING_MAX_LENGTH) { ERR(fp->handle, "policydb string length too long "); 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 ((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 ((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 (ebitmap_read(&p->policycaps, fp)) goto bad; } if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && p->policy_type == POLICY_KERN) { if (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]); nel = le32_to_cpu(buf[1]); for (j = 0; j < nel; j++) { if (read_f[i] (p, p->symtab[i].table, fp)) goto bad; } p->symtab[i].nprim = nprim; } if (policy_type == POLICY_KERN) { if (avtab_read(&p->te_avtab, fp, r_policyvers)) goto bad; if (r_policyvers >= POLICYDB_VERSION_BOOL) if (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->filename_trans, 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; } 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(p)) goto bad; if (policydb_index_classes(p)) goto bad; 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 = malloc(p->p_types.nprim * sizeof(ebitmap_t)); p->attr_type_map = malloc(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++) { ebitmap_init(&p->type_attr_map[i]); ebitmap_init(&p->attr_type_map[i]); } for (i = 0; i < p->p_types.nprim; i++) { if (r_policyvers >= POLICYDB_VERSION_AVTAB) { if (ebitmap_read(&p->type_attr_map[i], fp)) goto bad; ebitmap_for_each_bit(&p->type_attr_map[i], tnode, j) { if (!ebitmap_node_get_bit(tnode, j) || i == j) continue; if (ebitmap_set_bit (&p->attr_type_map[j], i, 1)) goto bad; } } /* add the type itself as the degenerate case */ if (ebitmap_set_bit(&p->type_attr_map[i], i, 1)) 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 **) malloc(p->p_users.nprim * sizeof(user_datum_t *)); if (!p->user_val_to_struct) return -1; p->sym_val_to_name[i] = (char **) malloc(p->symtab[i].nprim * sizeof(char *)); if (!p->sym_val_to_name[i]) return -1; if (hashtab_map(p->symtab[i].table, index_f[i], p)) return -1; /* Expand user roles for context validity checking */ if (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; } libsepol-2.4/src/policydb_convert.c000066400000000000000000000040721246370572200175030ustar00rootroot00000000000000#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 (policydb_read(policydb, &pf, 0)) { 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 (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 policydb_write. */ tmp_len = pf.len; tmp_data = pf.data; /* Write out the new policy image. */ if (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 (policydb_read(&tmp_policydb, &pf, 0)) { ERR(handle, "new policy image is invalid"); errno = EINVAL; goto err; } 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; } libsepol-2.4/src/policydb_internal.h000066400000000000000000000003661246370572200176460ustar00rootroot00000000000000#ifndef _SEPOL_POLICYDB_INTERNAL_H_ #define _SEPOL_POLICYDB_INTERNAL_H_ #include #include "dso.h" hidden_proto(sepol_policydb_create) hidden_proto(sepol_policydb_free) extern const char *policydb_target_strings[]; #endif libsepol-2.4/src/policydb_public.c000066400000000000000000000076711246370572200173110ustar00rootroot00000000000000#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); return -1; } return 0; } hidden_def(sepol_policydb_create) void sepol_policydb_free(sepol_policydb_t * p) { if (!p) return; policydb_destroy(&p->p); free(p); } hidden_def(sepol_policydb_free) 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_read(sepol_policydb_t * p, sepol_policy_file_t * pf) { return policydb_read(&p->p, &pf->pf, 0); } int sepol_policydb_write(sepol_policydb_t * p, sepol_policy_file_t * pf) { return 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); } libsepol-2.4/src/port_internal.h000066400000000000000000000011311246370572200170140ustar00rootroot00000000000000#ifndef _SEPOL_PORT_INTERNAL_H_ #define _SEPOL_PORT_INTERNAL_H_ #include #include #include "dso.h" hidden_proto(sepol_port_create) hidden_proto(sepol_port_free) hidden_proto(sepol_port_get_con) hidden_proto(sepol_port_get_high) hidden_proto(sepol_port_get_low) hidden_proto(sepol_port_get_proto) hidden_proto(sepol_port_get_proto_str) hidden_proto(sepol_port_key_create) hidden_proto(sepol_port_key_unpack) hidden_proto(sepol_port_set_con) hidden_proto(sepol_port_set_proto) hidden_proto(sepol_port_set_range) #endif libsepol-2.4/src/port_record.c000066400000000000000000000117261246370572200164640ustar00rootroot00000000000000#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; } hidden_def(sepol_port_key_create) 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; } hidden_def(sepol_port_key_unpack) 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; } hidden_def(sepol_port_get_low) int sepol_port_get_high(const sepol_port_t * port) { return port->high; } hidden_def(sepol_port_get_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; } hidden_def(sepol_port_set_range) /* Protocol */ int sepol_port_get_proto(const sepol_port_t * port) { return port->proto; } hidden_def(sepol_port_get_proto) const char *sepol_port_get_proto_str(int proto) { switch (proto) { case SEPOL_PROTO_UDP: return "udp"; case SEPOL_PROTO_TCP: return "tcp"; default: return "???"; } } hidden_def(sepol_port_get_proto_str) void sepol_port_set_proto(sepol_port_t * port, int proto) { port->proto = proto; } hidden_def(sepol_port_set_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; } hidden_def(sepol_port_create) /* 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); } hidden_def(sepol_port_free) /* Context */ sepol_context_t *sepol_port_get_con(const sepol_port_t * port) { return port->con; } hidden_def(sepol_port_get_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; } hidden_def(sepol_port_set_con) libsepol-2.4/src/ports.c000066400000000000000000000157171246370572200153150ustar00rootroot00000000000000#include #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; 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; 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; handle = NULL; 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; } libsepol-2.4/src/private.h000066400000000000000000000030061246370572200156110ustar00rootroot00000000000000/* Private definitions for libsepol. */ /* Endian conversion for reading and writing binary policies */ #include #ifdef DARWIN #include #include #else #include #include #endif #include #include #ifdef DARWIN #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])) /* 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 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) hidden; extern size_t put_entry(const void *ptr, size_t size, size_t n, struct policy_file *fp) hidden; libsepol-2.4/src/roles.c000066400000000000000000000023101246370572200152530ustar00rootroot00000000000000#include #include #include #include #include "debug.h" #include "handle.h" /* Check if a role exists */ int sepol_role_exists(sepol_handle_t * handle __attribute__ ((unused)), sepol_policydb_t * p, const char *role, int *response) { policydb_t *policydb = &p->p; *response = (hashtab_search(policydb->p_roles.table, (const hashtab_key_t)role) != NULL); handle = NULL; return STATUS_SUCCESS; } /* Fill an array with all valid roles */ int sepol_role_list(sepol_handle_t * handle, sepol_policydb_t * p, char ***roles, unsigned int *nroles) { policydb_t *policydb = &p->p; unsigned int tmp_nroles = policydb->p_roles.nprim; char **tmp_roles = (char **)malloc(tmp_nroles * sizeof(char *)); char **ptr; unsigned int i; if (!tmp_roles) goto omem; for (i = 0; i < tmp_nroles; i++) { tmp_roles[i] = strdup(policydb->p_role_val_to_name[i]); if (!tmp_roles[i]) goto omem; } *nroles = tmp_nroles; *roles = tmp_roles; return STATUS_SUCCESS; omem: ERR(handle, "out of memory, could not list roles"); ptr = tmp_roles; while (ptr && *ptr) free(*ptr++); free(tmp_roles); return STATUS_ERR; } libsepol-2.4/src/services.c000066400000000000000000001504271246370572200157670ustar00rootroot00000000000000 /* * 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. * * 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 "debug.h" #include "private.h" #include "context.h" #include "av_permissions.h" #include "dso.h" #include "mls.h" #define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) #define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) 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 = stack; int new_stack_len; if (stack_len == 0) new_stack_len = STACK_LEN; else new_stack_len = stack_len * 2; new_stack = realloc(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 hidden sepol_set_sidtab(sidtab_t * s) { sidtab = s; return 0; } int hidden 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) policydb_destroy(&mypolicydb); if (policydb_init(&mypolicydb)) { ERR(NULL, "Out of memory!"); return -1; } if (policydb_read(&mypolicydb, &pf, 0)) { policydb_destroy(&mypolicydb); ERR(NULL, "can't read binary policy: %s", strerror(errno)); 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 = e_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 = 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 = 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; /* Find if MLS statement or not */ mls = 0; for (e = constraint->expr; e; e = e->next) { if (e->attr >= CEXPR_L1L2) { mls = 1; break; } } /* Determine statement type */ const char *statements[] = { "constrain ", /* 0 */ "mlsconstrain ", /* 1 */ "validatetrans ", /* 2 */ "mlsvalidatetrans ", /* 3 */ 0 }; if (xcontext == NULL) state_num = mls + 0; else state_num = mls + 2; int class_buf_len = 0; int new_class_buf_len; int len, buf_used; char *class_buf = NULL, *p; char *new_class_buf = NULL; 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) 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 || 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 || 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 || 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 = SOURCE; /* 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; /* * The array of expression answer buffer pointers and counter. */ char **answer_list = NULL; int answer_counter = 0; 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 */ int expr_list_len = 0; 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 = 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 = realloc(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: BUG_ON(sp < 0); s[sp] = !s[sp]; cat_expr_buf(expr_list[expr_counter], "not"); break; case CEXPR_AND: BUG_ON(sp < 1); sp--; s[sp] &= s[sp + 1]; cat_expr_buf(expr_list[expr_counter], "and"); break; case CEXPR_OR: BUG_ON(sp < 1); 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] = ebitmap_get_bit(&r1->dominates, val2 - 1); msgcat(src, tgt, "dom", s[sp] == 0); expr_counter++; continue; case CEXPR_DOMBY: s[++sp] = ebitmap_get_bit(&r2->dominates, val1 - 1); msgcat(src, tgt, "domby", s[sp] == 0); expr_counter++; continue; case CEXPR_INCOMP: s[++sp] = (!ebitmap_get_bit(&r1->dominates, val2 - 1) && !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] = ebitmap_get_bit(&e->names, val1 - 1); get_name_list(e, u_r_t, src, "==", s[sp] == 0); break; case CEXPR_NEQ: s[++sp] = !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. */ int 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 = malloc(expr_count * sizeof(*answer_list)); if (!answer_list) { ERR(NULL, "failed to allocate answer stack"); rc = -ENOMEM; goto out; } /* The pop operands */ char *a; char *b; int a_len, b_len; /* 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"); 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 }; /* * 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)))) { for (x = 0; buffers[x] != NULL; x++) { while (1) { p = *r_buf + reason_buf_used; 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; } /* * 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; *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_bit(sattr, snode, i) { if (!ebitmap_node_get_bit(snode, i)) continue; ebitmap_for_each_bit(tattr, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; avkey.source_type = i + 1; avkey.target_type = j + 1; for (node = avtab_search_node(&policydb->te_avtab, &avkey); node != NULL; node = 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 */ cond_compute_av(&policydb->te_cond_avtab, &avkey, avd); } } if (requested & ~avd->allowed) { *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) { *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 == SECCLASS_PROCESS && (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && 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 = (avd->allowed) & ~(PROCESS__TRANSITION | PROCESS__DYNTRANSITION); } if (requested & ~avd->allowed) { *reason |= SEPOL_COMPUTEAV_RBAC; requested &= avd->allowed; } return 0; } int hidden sepol_validate_transition(sepol_security_id_t oldsid, sepol_security_id_t newsid, sepol_security_id_t tasksid, sepol_security_class_t tclass) { 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; } constraint = tclass_datum->validatetrans; while (constraint) { if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext, 0, constraint, NULL, 0)) { return -EPERM; } constraint = constraint->next; } return 0; } /* * sepol_validate_transition_reason_buffer - the reason buffer is realloc'd * in the constraint_expr_eval_reason() function. */ int hidden 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 hidden 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 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; } 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 hidden 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 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; } /* * 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 hidden 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 hidden sepol_string_to_security_class(const char *class_name, sepol_security_class_t *tclass) { char *class = NULL; sepol_security_class_t id; for (id = 1;; id++) { class = policydb->p_class_val_to_name[id - 1]; if (class == NULL) { ERR(NULL, "could not convert %s to class id", class_name); return STATUS_ERR; } if ((strcmp(class, class_name)) == 0) { *tclass = id; return STATUS_SUCCESS; } } } /* * Return access vector bit associated with the class ID and permission * string. */ int hidden 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, (hashtab_key_t)perm_name); if (perm_datum != NULL) { *av = 0x1 << (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, (hashtab_key_t)perm_name); if (perm_datum != NULL) { *av = 0x1 << (perm_datum->s.value - 1); return STATUS_SUCCESS; } out: ERR(NULL, "could not convert %s to av bit", perm_name); return STATUS_ERR; } /* * 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 hidden 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 hidden sepol_context_to_sid(const sepol_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) { 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; } context_init(&newcontext); /* Set the user identity. */ switch (specified) { case AVTAB_TRANSITION: case AVTAB_CHANGE: /* 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 and type to default values. */ switch (tclass) { case SECCLASS_PROCESS: /* Use the current role and type of process. */ newcontext.role = scontext->role; newcontext.type = scontext->type; break; default: /* Use the well-defined object role. */ newcontext.role = OBJECT_R_VAL; /* 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 = avtab_search(&policydb->te_avtab, &avkey); /* If no permanent rule, also check for enabled conditional rules */ if (!avdatum) { node = avtab_search_node(&policydb->te_cond_avtab, &avkey); for (; node != NULL; node = 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. */ switch (tclass) { case SECCLASS_PROCESS: 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) { /* Use the role transition rule. */ newcontext.role = roletr->new_role; break; } } } break; default: break; } /* Set the MLS attributes. This is done last because it may allocate memory. */ rc = mls_compute_sid(policydb, scontext, tcontext, tclass, specified, &newcontext); if (rc) goto out; /* Check the validity of the context. */ if (!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 hidden 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 hidden 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 hidden 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 (hashtab_map (cladatum->comdatum->permissions.table, validate_perm, cladatum2->comdatum->permissions.table)) { ERR(NULL, " in the access vector definition " "for class %s\n", key); return -1; } } if (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 = mls_convert_context(args->oldp, args->newp, c); if (rc) goto bad; /* Check the validity of the new context. */ if (!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 hidden next_entry(void *buf, struct policy_file *fp, size_t bytes) { size_t nread; switch (fp->type) { case PF_USE_STDIO: nread = fread(buf, bytes, 1, fp->fp); if (nread != 1) return -1; break; case PF_USE_MEMORY: if (bytes > fp->len) return -1; memcpy(buf, fp->data, bytes); fp->data += bytes; fp->len -= bytes; break; default: return -1; } return 0; } size_t hidden 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); 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; } /* * 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 hidden 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 (policydb_read(&newpolicydb, fp, 1)) { policydb_destroy(&mypolicydb); return -EINVAL; } sepol_sidtab_init(&newsidtab); /* Verify that the existing classes did not change. */ if (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. */ policydb_destroy(&oldpolicydb); sepol_sidtab_destroy(&oldsidtab); return 0; err: sepol_sidtab_destroy(&newsidtab); 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 hidden 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 port specified by * `domain', `type', `protocol', and `port'. */ int hidden 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 hidden 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 hidden 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 hidden 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 = malloc(maxnel * sizeof(sepol_security_id_t)); if (!mysids) { rc = -ENOMEM; goto out; } memset(mysids, 0, maxnel * sizeof(sepol_security_id_t)); ebitmap_for_each_bit(&user->roles.roles, rnode, i) { if (!ebitmap_node_get_bit(rnode, i)) continue; role = policydb->role_val_to_struct[i]; usercon.role = i + 1; ebitmap_for_each_bit(&role->types.types, tnode, j) { if (!ebitmap_node_get_bit(tnode, j)) continue; usercon.type = j + 1; if (usercon.type == fromcon->type) continue; if (mls_setup_user_range (fromcon, user, &usercon, policydb->mls)) continue; rc = context_struct_compute_av(fromcon, &usercon, SECCLASS_PROCESS, PROCESS__TRANSITION, &avd, &reason, NULL, 0); if (rc || !(avd.allowed & PROCESS__TRANSITION)) 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 = malloc(maxnel * sizeof(sepol_security_id_t)); if (!mysids2) { rc = -ENOMEM; free(mysids); goto out; } memset(mysids2, 0, maxnel * sizeof(sepol_security_id_t)); 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 hidden 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 hidden 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, "/", SECCLASS_DIR, sid); if (rc) { *behavior = SECURITY_FS_USE_NONE; rc = 0; } else { *behavior = SECURITY_FS_USE_GENFS; } } out: return rc; } /* FLASK */ libsepol-2.4/src/sidtab.c000066400000000000000000000136501246370572200154060ustar00rootroot00000000000000 /* Author : Stephen Smalley, */ /* FLASK */ /* * Implementation of the SID table type. */ #include #include #include #include #include #include #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) { int i; s->htable = malloc(sizeof(sidtab_ptr_t) * SIDTAB_SIZE); if (!s->htable) return -ENOMEM; for (i = 0; i < SIDTAB_SIZE; i++) s->htable[i] = (sidtab_ptr_t) NULL; 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; } int sepol_sidtab_remove(sidtab_t * s, sepol_security_id_t sid) { int hvalue; sidtab_node_t *cur, *last; if (!s || !s->htable) return -ENOENT; hvalue = SIDTAB_HASH(sid); last = NULL; cur = s->htable[hvalue]; while (cur != NULL && sid > cur->sid) { last = cur; cur = cur->next; } if (cur == NULL || sid != cur->sid) return -ENOENT; if (last == NULL) s->htable[hvalue] = cur->next; else last->next = cur->next; context_destroy(&cur->context); free(cur); s->nel--; 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 */ libsepol-2.4/src/symtab.c000066400000000000000000000020021246370572200154240ustar00rootroot00000000000000 /* Author : Stephen Smalley, */ /* FLASK */ /* * Implementation of the symbol table type. */ #include #include #include static unsigned int symhash(hashtab_t h, hashtab_key_t key) { char *p, *keyp; size_t size; unsigned int val; val = 0; keyp = (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)), hashtab_key_t key1, hashtab_key_t key2) { char *keyp1, *keyp2; keyp1 = (char *)key1; keyp2 = (char *)key2; return strcmp(keyp1, keyp2); } int 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) hashtab_destroy(s->table); return; } /* FLASK */ libsepol-2.4/src/user_internal.h000066400000000000000000000011451246370572200170130ustar00rootroot00000000000000#ifndef _SEPOL_USER_INTERNAL_H_ #define _SEPOL_USER_INTERNAL_H_ #include #include #include "dso.h" hidden_proto(sepol_user_add_role) hidden_proto(sepol_user_create) hidden_proto(sepol_user_free) hidden_proto(sepol_user_get_mlslevel) hidden_proto(sepol_user_get_mlsrange) hidden_proto(sepol_user_get_roles) hidden_proto(sepol_user_has_role) hidden_proto(sepol_user_key_create) hidden_proto(sepol_user_key_unpack) hidden_proto(sepol_user_set_mlslevel) hidden_proto(sepol_user_set_mlsrange) hidden_proto(sepol_user_set_name) #endif libsepol-2.4/src/user_record.c000066400000000000000000000164661246370572200164640ustar00rootroot00000000000000#include #include #include #include "user_internal.h" #include "debug.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 */ const 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 = name; *key_ptr = tmp_key; return STATUS_SUCCESS; } hidden_def(sepol_user_key_create) void sepol_user_key_unpack(const sepol_user_key_t * key, const char **name) { *name = key->name; } hidden_def(sepol_user_key_unpack) 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) { 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; } hidden_def(sepol_user_set_name) /* MLS */ const char *sepol_user_get_mlslevel(const sepol_user_t * user) { return user->mls_level; } hidden_def(sepol_user_get_mlslevel) 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; } hidden_def(sepol_user_set_mlslevel) const char *sepol_user_get_mlsrange(const sepol_user_t * user) { return user->mls_range; } hidden_def(sepol_user_get_mlsrange) 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; } hidden_def(sepol_user_set_mlsrange) /* 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; if (sepol_user_has_role(user, role)) return STATUS_SUCCESS; role_cp = strdup(role); roles_realloc = realloc(user->roles, sizeof(char *) * (user->num_roles + 1)); if (!role_cp || !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; } hidden_def(sepol_user_add_role) 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; } hidden_def(sepol_user_has_role) 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 **)malloc(sizeof(char *) * user->num_roles); 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; } hidden_def(sepol_user_get_roles) 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; } hidden_def(sepol_user_create) /* 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); } hidden_def(sepol_user_free) libsepol-2.4/src/users.c000066400000000000000000000212021246370572200152710ustar00rootroot00000000000000#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 = &(usrdatum->roles.roles); ebitmap_node_t *rnode; unsigned bit; sepol_user_t *tmp_record = NULL; 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_bit(roles, rnode, bit) { if (ebitmap_node_get_bit(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, (const hashtab_key_t)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, (const hashtab_key_t)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_bit(&roldatum->dominates, rnode, bit) { if (ebitmap_node_get_bit(rnode, bit)) { if (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 (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 (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 = realloc(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; tmp_ptr = realloc(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; /* 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, (const hashtab_key_t)cname) != NULL); handle = 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; handle = NULL; 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, (const hashtab_key_t)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; } libsepol-2.4/src/util.c000066400000000000000000000060751246370572200151200ustar00rootroot00000000000000/* 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 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) { 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) *a = (uint32_t *) realloc(*a, (*cnt + 1) * sizeof(uint32_t)); else { /* empty list */ *cnt = 0; *a = (uint32_t *) malloc(sizeof(uint32_t)); } if (*a == NULL) { return -1; } (*a)[*cnt] = i; (*cnt)++; 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; cladatum = policydbp->class_val_to_struct[tclass - 1]; p = avbuf; for (i = 0; i < cladatum->permissions.nprim; i++) { if (av & (1 << i)) { v.val = i + 1; rc = hashtab_map(cladatum->permissions.table, perm_name, &v); if (!rc && cladatum->comdatum) { rc = 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; } libsepol-2.4/src/write.c000066400000000000000000001537261246370572200153030ustar00rootroot00000000000000 /* 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 * * 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" #include "private.h" #include "mls.h" struct policy_data { struct policy_file *fp; struct policydb *p; }; static int avrule_write_list(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; 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 = avtab_search_node_next(cur, lookup); node; node = 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 = 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; 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 (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) 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 == SECCLASS_PROCESS) 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 != SECCLASS_PROCESS) { 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_trans_write(filename_trans_t * r, struct policy_file *fp) { filename_trans_t *ft; uint32_t buf[4]; size_t nel, items, len; nel = 0; for (ft = r; ft; ft = ft->next) nel++; buf[0] = cpu_to_le32(nel); items = put_entry(buf, sizeof(uint32_t), 1, fp); if (items != 1) return POLICYDB_ERROR; for (ft = r; ft; ft = ft->next) { 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; buf[0] = cpu_to_le32(ft->stype); buf[1] = cpu_to_le32(ft->ttype); buf[2] = cpu_to_le32(ft->tclass); buf[3] = cpu_to_le32(ft->otype); items = put_entry(buf, sizeof(uint32_t), 4, fp); if (items != 4) return POLICYDB_ERROR; } return POLICYDB_SUCCESS; } 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 (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); 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(node->avtrue_list, fp)) return POLICYDB_ERROR; if (avrule_write_list(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 (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) { items = 0; 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 (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); 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 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 (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(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { unsigned int i, j; size_t nel, items; 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) 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: 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: 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; } } } return POLICYDB_SUCCESS; } static int ocontext_write_selinux(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) 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: 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_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(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; } static int range_write(policydb_t * p, struct policy_file *fp) { size_t nel, items; struct range_trans *rt; uint32_t buf[2]; int new_rangetr = (p->policy_type == POLICY_KERN && p->policyvers >= POLICYDB_VERSION_RANGETRANS); int warning_issued = 0; nel = 0; for (rt = p->range_tr; rt; rt = rt->next) { /* all range_transitions are written for the new format, only process related range_transitions are written for the old format, so count accordingly */ if (new_rangetr || rt->target_class == SECCLASS_PROCESS) nel++; } buf[0] = cpu_to_le32(nel); items = put_entry(buf, sizeof(uint32_t), 1, fp); if (items != 1) return POLICYDB_ERROR; for (rt = p->range_tr; rt; rt = rt->next) { if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) { if (!warning_issued) WARN(fp->handle, "Discarding range_transition " "rules for security classes other than " "\"process\""); warning_issued = 1; continue; } 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; } if (mls_write_range_helper(&rt->target_range, fp)) return POLICYDB_ERROR; } return POLICYDB_SUCCESS; } /************** module writing functions below **************/ static int avrule_write(avrule_t * avrule, struct policy_file *fp) { size_t items, items2; uint32_t buf[32], len; class_perm_node_t *cur; 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; } return POLICYDB_SUCCESS; } static int avrule_write_list(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) { avrule_write(avrule, fp); avrule = avrule->next; } return POLICYDB_SUCCESS; } static int only_process(ebitmap_t *in) { unsigned int i; ebitmap_node_t *node; ebitmap_for_each_bit(in, node, i) { if (ebitmap_node_get_bit(node, i) && i != SECCLASS_PROCESS - 1) 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)) 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)) { 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(filename_trans_rule_t * t, struct policy_file *fp) { int nel = 0; size_t items; uint32_t buf[2], 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); items = put_entry(buf, sizeof(uint32_t), 2, fp); if (items != 2) 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(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(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 (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 = malloc(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 policydb_write(policydb_t * p, struct policy_file *fp) { unsigned int i, num_syms; uint32_t buf[32], config; size_t items, items2, len; 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_bit(&p->permissive_map, tnode, i) { if (ebitmap_node_get_bit(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) { 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)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 (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->filename_trans, 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 (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; } libsepol-2.4/tests/000077500000000000000000000000001246370572200143425ustar00rootroot00000000000000libsepol-2.4/tests/Makefile000066400000000000000000000034161246370572200160060ustar00rootroot00000000000000M4 ?= 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/ CPPFLAGS += -I../include/ -I$(CHECKPOLICY) # test program object files objs := $(patsubst %.c,%.o,$(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) $(CFLAGS) $(CPPFLAGS) $(objs) $(parserobjs) -lfl -lcunit -lcurses $(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 test: $(EXE) $(policies) $(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 libsepol-2.4/tests/debug.c000066400000000000000000000034431246370572200156000ustar00rootroot00000000000000/* * 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", 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; } } } libsepol-2.4/tests/debug.h000066400000000000000000000022111246370572200155750ustar00rootroot00000000000000/* * 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); libsepol-2.4/tests/helpers.c000066400000000000000000000042151246370572200161520ustar00rootroot00000000000000/* * 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); policydb_destroy(p); return -1; } return 0; } avrule_decl_t *test_find_decl_by_sym(policydb_t * p, int symtab, 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]; } libsepol-2.4/tests/helpers.h000066400000000000000000000043601246370572200161600ustar00rootroot00000000000000/* * 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 /* helper functions */ /* 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, char *sym); #endif libsepol-2.4/tests/libsepol-tests.c000066400000000000000000000052341246370572200174630ustar00rootroot00000000000000/* * 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 int mls; #define DECLARE_SUITE(name) \ 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(); } 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 int do_tests(int interactive, int verbose) { CU_pSuite suite = NULL; 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(); CU_cleanup_registry(); return CU_get_error(); } 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; } libsepol-2.4/tests/policies/000077500000000000000000000000001246370572200161515ustar00rootroot00000000000000libsepol-2.4/tests/policies/support/000077500000000000000000000000001246370572200176655ustar00rootroot00000000000000libsepol-2.4/tests/policies/support/misc_macros.spt000066400000000000000000000011751246370572200227200ustar00rootroot00000000000000 ######################################## # # 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 libsepol-2.4/tests/policies/test-cond/000077500000000000000000000000001246370572200200515ustar00rootroot00000000000000libsepol-2.4/tests/policies/test-cond/refpolicy-base.conf000066400000000000000000002061161246370572200236320ustar00rootroot00000000000000class 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 libsepol-2.4/tests/policies/test-deps/000077500000000000000000000000001246370572200200615ustar00rootroot00000000000000libsepol-2.4/tests/policies/test-deps/base-metreq.conf000066400000000000000000000164401246370572200231420ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(system_u:object_r:net_foo_t, s0) libsepol-2.4/tests/policies/test-deps/base-notmetreq.conf000066400000000000000000000161741246370572200236670ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(system_u:object_r:net_foo_t, s0) libsepol-2.4/tests/policies/test-deps/modreq-attr-global.conf000066400000000000000000000001561246370572200244270ustar00rootroot00000000000000module modreq_attr_global 1.0; require { attribute attr_req; } type mod_global_t; type new_t, attr_req; libsepol-2.4/tests/policies/test-deps/modreq-attr-opt.conf000066400000000000000000000002641246370572200237710ustar00rootroot00000000000000module 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; } libsepol-2.4/tests/policies/test-deps/modreq-bool-global.conf000066400000000000000000000002731246370572200244100ustar00rootroot00000000000000module 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 }; } libsepol-2.4/tests/policies/test-deps/modreq-bool-opt.conf000066400000000000000000000003541246370572200237520ustar00rootroot00000000000000module 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 }; } } libsepol-2.4/tests/policies/test-deps/modreq-obj-global.conf000066400000000000000000000002661246370572200242310ustar00rootroot00000000000000module 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 }; libsepol-2.4/tests/policies/test-deps/modreq-obj-opt.conf000066400000000000000000000003741246370572200235730ustar00rootroot00000000000000module 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 }; } libsepol-2.4/tests/policies/test-deps/modreq-perm-global.conf000066400000000000000000000002271246370572200244170ustar00rootroot00000000000000module 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 }; libsepol-2.4/tests/policies/test-deps/modreq-perm-opt.conf000066400000000000000000000003621246370572200237610ustar00rootroot00000000000000module 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 }; } libsepol-2.4/tests/policies/test-deps/modreq-role-global.conf000066400000000000000000000002361246370572200244150ustar00rootroot00000000000000module 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; libsepol-2.4/tests/policies/test-deps/modreq-role-opt.conf000066400000000000000000000002751246370572200237620ustar00rootroot00000000000000module 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; } libsepol-2.4/tests/policies/test-deps/modreq-type-global.conf000066400000000000000000000002551246370572200244360ustar00rootroot00000000000000module 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 }; libsepol-2.4/tests/policies/test-deps/modreq-type-opt.conf000066400000000000000000000003271246370572200240000ustar00rootroot00000000000000module 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 }; }libsepol-2.4/tests/policies/test-deps/module.conf000066400000000000000000000004721246370572200222200ustar00rootroot00000000000000module 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 }; } libsepol-2.4/tests/policies/test-deps/small-base.conf000066400000000000000000000161551246370572200227600ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(system_u:object_r:net_foo_t, s0) libsepol-2.4/tests/policies/test-expander/000077500000000000000000000000001246370572200207345ustar00rootroot00000000000000libsepol-2.4/tests/policies/test-expander/alias-base.conf000066400000000000000000000154211246370572200236070ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(system_u:object_r:system_t, s0) libsepol-2.4/tests/policies/test-expander/alias-module.conf000066400000000000000000000001561246370572200241610ustar00rootroot00000000000000module my_module 1.0; require { type alias_check_3_t; } typealias alias_check_3_t alias alias_check_3_a; libsepol-2.4/tests/policies/test-expander/base-base-only.conf000066400000000000000000000007231246370572200244060ustar00rootroot00000000000000class 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) libsepol-2.4/tests/policies/test-expander/module.conf000066400000000000000000000140671246370572200231000ustar00rootroot00000000000000module 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; } libsepol-2.4/tests/policies/test-expander/role-base.conf000066400000000000000000000150241246370572200234560ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(system_u:object_r:system_t, s0) libsepol-2.4/tests/policies/test-expander/role-module.conf000066400000000000000000000002241246370572200240250ustar00rootroot00000000000000module 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; libsepol-2.4/tests/policies/test-expander/small-base.conf000066400000000000000000000313651246370572200236330ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(system_u:object_r:net_foo_t, s0) libsepol-2.4/tests/policies/test-expander/user-base.conf000066400000000000000000000153071246370572200234770ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(system_u:object_r:system_t, s0) libsepol-2.4/tests/policies/test-expander/user-module.conf000066400000000000000000000001531246370572200240430ustar00rootroot00000000000000module my_module 1.0; require { class file {read write}; ifdef(`enable_mls',` user user_check_1; ') } libsepol-2.4/tests/policies/test-hooks/000077500000000000000000000000001246370572200202515ustar00rootroot00000000000000libsepol-2.4/tests/policies/test-hooks/cmp_policy.conf000066400000000000000000000144031246370572200232600ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(g_b_user_1:object_r:g_b_type_1, s0) libsepol-2.4/tests/policies/test-hooks/module_add_role_allow_trans.conf000066400000000000000000000003251246370572200266430ustar00rootroot00000000000000module 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; libsepol-2.4/tests/policies/test-hooks/module_add_symbols.conf000066400000000000000000000003301246370572200247610ustar00rootroot00000000000000module 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 }; ') libsepol-2.4/tests/policies/test-hooks/small-base.conf000066400000000000000000000144031246370572200231420ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(g_b_user_1:object_r:g_b_type_1, s0) libsepol-2.4/tests/policies/test-linker/000077500000000000000000000000001246370572200204125ustar00rootroot00000000000000libsepol-2.4/tests/policies/test-linker/module1.conf000066400000000000000000000055751246370572200226430ustar00rootroot00000000000000module 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; } libsepol-2.4/tests/policies/test-linker/module2.conf000066400000000000000000000023651246370572200226360ustar00rootroot00000000000000module 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; } libsepol-2.4/tests/policies/test-linker/small-base.conf000066400000000000000000000207661246370572200233140ustar00rootroot00000000000000# 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 controling capabilies # 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:: gen_context(g_b_user_1:object_r:g_b_type_1, s0) libsepol-2.4/tests/test-common.c000066400000000000000000000167661246370572200167730ustar00rootroot00000000000000/* * 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 void test_sym_presence(policydb_t * p, 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++) { hashtab_map(p->symtab[i].table, test_index_f[i], p); } } void test_alias_datum(policydb_t * p, char *id, 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 if (my_flavor == TYPE_ALIAS) { my_primary = primary->s.value; CU_ASSERT_NOT_EQUAL(type->s.value, primary->s.value); my_value = type->s.value; } else { CU_FAIL("not an alias"); } 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, char *id, avrule_decl_t * decl, 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_bit(&role->types.types, tnode, i) { if (ebitmap_node_get_bit(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, char *id, avrule_decl_t * decl, 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); else attr = hashtab_search(p->p_types.table, id); if (attr == NULL) printf("could not find attr %s in decl %d\n", id, decl->decl_id); CU_ASSERT_FATAL(attr != NULL); CU_ASSERT(attr->flavor == TYPE_ATTRIB); CU_ASSERT(attr->primary == 1); ebitmap_for_each_bit(&attr->types, tnode, i) { if (ebitmap_node_get_bit(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); } libsepol-2.4/tests/test-common.h000066400000000000000000000066121246370572200167650ustar00rootroot00000000000000/* * 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, 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, char *id, 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, char *id, avrule_decl_t * decl, 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, char *id, avrule_decl_t * decl, char **types, int len); #endif libsepol-2.4/tests/test-cond.c000066400000000000000000000043751246370572200164170ustar00rootroot00000000000000/* * 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"); 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: policydb_destroy(&basemod); policydb_destroy(&base_expanded); return -1; } int cond_test_cleanup(void) { policydb_destroy(&basemod); 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; } libsepol-2.4/tests/test-cond.h000066400000000000000000000020101246370572200164040ustar00rootroot00000000000000/* * 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 libsepol-2.4/tests/test-deps.c000066400000000000000000000237341246370572200164270ustar00rootroot00000000000000/* * 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 #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++) { policydb_destroy(&bases_met[i]); } for (i = 0; i < NUM_BASES; i++) { 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. * * Paramaters: * 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, char *policy, 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); policydb_destroy(&mod); 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. * * Paramaters: * 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, char *policy, 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); policydb_destroy(&mod); 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; } libsepol-2.4/tests/test-deps.h000066400000000000000000000020101246370572200164140ustar00rootroot00000000000000/* * 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 libsepol-2.4/tests/test-downgrade.c000066400000000000000000000160771246370572200174500ustar00rootroot00000000000000/* * 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) { 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 compatability 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 */ 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; } 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)); sepol_handle_destroy(f.handle); return -1; } /* Read in the binary policy. */ memset(&f, 0, sizeof(struct policy_file)); f.type = PF_USE_STDIO; f.fp = in_fp; rc = policydb_read(p, &f, 0); sepol_handle_destroy(f.handle); 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(f.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 = policydb_write(p, &f); sepol_handle_destroy(f.handle); fclose(out_fp); return rc; } libsepol-2.4/tests/test-downgrade.h000066400000000000000000000065601246370572200174510ustar00rootroot00000000000000/* * 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 compatability 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 libsepol-2.4/tests/test-expander-attr-map.c000066400000000000000000000134741246370572200210250ustar00rootroot00000000000000/* * 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 #include #include extern policydb_t base_expanded2; void test_expander_attr_mapping(void) { /* note that many cases are ommitted 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 */ char *typesb1[] = { "attr_check_base_1_1_t", "attr_check_base_1_2_t" }; char *typesb2[] = { "attr_check_base_2_1_t", "attr_check_base_2_2_t" }; 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" }; char *typesb4[] = { "attr_check_base_4_1_t", "attr_check_base_4_2_t" }; char *typesb5[] = { "attr_check_base_5_1_t", "attr_check_base_5_2_t" }; 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" }; char *typesbo2[] = { "attr_check_base_optional_2_1_t", "attr_check_base_optional_2_2_t" }; char *typesbo5[] = { "attr_check_base_optional_5_1_t", "attr_check_base_optional_5_2_t" }; char *typesm2[] = { "attr_check_mod_2_1_t", "attr_check_mod_2_2_t" }; char *typesm4[] = { "attr_check_mod_4_1_t", "attr_check_mod_4_2_t" }; char *typesm5[] = { "attr_check_mod_5_1_t", "attr_check_mod_5_2_t" }; 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" }; char *typesmo2[] = { "attr_check_mod_optional_4_1_t", "attr_check_mod_optional_4_2_t" }; char *typesb10[] = { "attr_check_base_10_1_t", "attr_check_base_10_2_t" }; char *typesb11[] = { "attr_check_base_11_3_t", "attr_check_base_11_4_t" }; char *typesm10[] = { "attr_check_mod_10_1_t", "attr_check_mod_10_2_t" }; 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")); } libsepol-2.4/tests/test-expander-attr-map.h000066400000000000000000000017231246370572200210240ustar00rootroot00000000000000/* * 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 libsepol-2.4/tests/test-expander-roles.c000066400000000000000000000024331246370572200204150ustar00rootroot00000000000000/* * 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 #include #include extern policydb_t role_expanded; void test_expander_role_mapping(void) { 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); } libsepol-2.4/tests/test-expander-roles.h000066400000000000000000000017721246370572200204270ustar00rootroot00000000000000/* * 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 libsepol-2.4/tests/test-expander-users.c000066400000000000000000000044121246370572200204310ustar00rootroot00000000000000/* * 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 #include #include extern policydb_t user_expanded; static void check_user_roles(policydb_t * p, char *user_name, 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_bit(&user->roles.roles, tnode, i) { if (ebitmap_node_get_bit(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) { char *roles1[] = { "user_check_1_1_r", "user_check_1_2_r" }; check_user_roles(&user_expanded, "user_check_1", roles1, 2); } libsepol-2.4/tests/test-expander-users.h000066400000000000000000000017721246370572200204440ustar00rootroot00000000000000/* * 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 libsepol-2.4/tests/test-expander.c000066400000000000000000000142701246370572200172750ustar00rootroot00000000000000/* * 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 */ int expander_policy_init(policydb_t * mybase, int num_modules, policydb_t ** mymodules, policydb_t * myexpanded, char **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; } return 0; } int expander_test_init(void) { char *small_base_file = "small-base.conf"; char *base_only_file = "base-base-only.conf"; int rc; policydb_t *mymod2; char *files2[] = { "small-base.conf", "module.conf" }; char *role_files[] = { "role-base.conf", "role-module.conf" }; char *user_files[] = { "user-base.conf", "user-module.conf" }; 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) { policydb_destroy(&basemod); policydb_destroy(&base_expanded); 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; } libsepol-2.4/tests/test-expander.h000066400000000000000000000020321246370572200172730ustar00rootroot00000000000000/* * 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 libsepol-2.4/tests/test-linker-cond-map.c000066400000000000000000000120501246370572200204410ustar00rootroot00000000000000/* * 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 "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 { char *bool; uint32_t expr_type; } test_cond_expr_t; 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; } } void test_bool_state(policydb_t * p, 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 existance 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 existance 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 existance 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 existance 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 existance 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); } libsepol-2.4/tests/test-linker-cond-map.h000066400000000000000000000020101246370572200204410ustar00rootroot00000000000000/* * 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__ extern void base_cond_tests(policydb_t * base); extern void module_cond_tests(policydb_t * base); #endif libsepol-2.4/tests/test-linker-roles.c000066400000000000000000000215671246370572200201040ustar00rootroot00000000000000/* * 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 "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_bit(&role->dominates, tnode, i) { if (ebitmap_node_get_bit(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]; 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]; 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; decls[1] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; test_sym_presence(base, "g_b_role_2", SYM_ROLES, SCOPE_DECL, decls, 2); /* 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); } libsepol-2.4/tests/test-linker-roles.h000066400000000000000000000020501246370572200200730ustar00rootroot00000000000000/* * 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 libsepol-2.4/tests/test-linker-types.c000066400000000000000000000352031246370572200201140ustar00rootroot00000000000000/* * 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 "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, 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]; 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]; 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); } libsepol-2.4/tests/test-linker-types.h000066400000000000000000000020021246370572200201100ustar00rootroot00000000000000/* * 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__ extern void base_type_tests(policydb_t * base); extern void module_type_tests(policydb_t * base); #endif libsepol-2.4/tests/test-linker.c000066400000000000000000000073331246370572200167550ustar00rootroot00000000000000/* * 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; policydb_destroy(&basenomods); policydb_destroy(&linkedbase); for (i = 0; i < NUM_MODS; i++) { 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; } libsepol-2.4/tests/test-linker.h000066400000000000000000000020201246370572200167460ustar00rootroot00000000000000/* * 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 libsepol-2.4/utils/000077500000000000000000000000001246370572200143405ustar00rootroot00000000000000libsepol-2.4/utils/Makefile000066400000000000000000000006041246370572200160000ustar00rootroot00000000000000# Installation directories. PREFIX ?= $(DESTDIR)/usr BINDIR ?= $(PREFIX)/bin CFLAGS ?= -Wall -Werror override CFLAGS += -I../include LDLIBS += -L../src -lsepol TARGETS=$(patsubst %.c,%,$(wildcard *.c)) all: $(TARGETS) install: all -mkdir -p $(BINDIR) install -m 755 $(TARGETS) $(BINDIR) clean: -rm -f $(TARGETS) *.o indent: ../../scripts/Lindent $(wildcard *.[ch]) relabel: libsepol-2.4/utils/chkcon.c000066400000000000000000000014421246370572200157520ustar00rootroot00000000000000#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); }