From: <mad...@us...> - 2006-09-28 12:17:30
|
Revision: 2035 http://svn.sourceforge.net/selinux/?rev=2035&view=rev Author: madmethod Date: 2006-09-28 05:16:58 -0700 (Thu, 28 Sep 2006) Log Message: ----------- tag for checkpolicy 1.30.12 Added Paths: ----------- tags/checkpolicy_1_30_12/ tags/checkpolicy_1_30_12/checkpolicy/ tags/checkpolicy_1_30_12/checkpolicy/ChangeLog tags/checkpolicy_1_30_12/checkpolicy/VERSION tags/checkpolicy_1_30_12/checkpolicy/module_compiler.c tags/checkpolicy_1_30_12/checkpolicy/module_compiler.h tags/checkpolicy_1_30_12/checkpolicy/policy_parse.y Removed Paths: ------------- tags/checkpolicy_1_30_12/checkpolicy/ChangeLog tags/checkpolicy_1_30_12/checkpolicy/VERSION tags/checkpolicy_1_30_12/checkpolicy/module_compiler.c tags/checkpolicy_1_30_12/checkpolicy/module_compiler.h tags/checkpolicy_1_30_12/checkpolicy/policy_parse.y Copied: tags/checkpolicy_1_30_12/checkpolicy (from rev 2032, trunk/checkpolicy) Deleted: tags/checkpolicy_1_30_12/checkpolicy/ChangeLog =================================================================== --- trunk/checkpolicy/ChangeLog 2006-09-18 19:13:13 UTC (rev 2032) +++ tags/checkpolicy_1_30_12/checkpolicy/ChangeLog 2006-09-28 12:16:58 UTC (rev 2035) @@ -1,285 +0,0 @@ -1.30.11 2006-09-05 - * merged range_transition enhancements and user module format - changes from Darrel Goeddel - -1.30.10 2006-08-03 - * Merged symtab datum patch from Karl MacMillan. - -1.30.9 2006-06-29 - * Lindent. - -1.30.8 2006-06-29 - * Merged patch to remove TE rule conflict checking from the parser - from Joshua Brindle. This can only be done properly by the - expander. - -1.30.7 2006-06-27 - * Merged patch to make checkpolicy/checkmodule handling of - duplicate/conflicting TE rules the same as the expander - from Joshua Brindle. - -1.30.6 2006-06-26 - * Merged optionals in base take 2 patch set from Joshua Brindle. - -1.30.5 2006-05-05 - * Merged compiler cleanup patch from Karl MacMillan. - * Merged fix warnings patch from Karl MacMillan. - -1.30.4 2006-04-05 - * Changed require_class to reject permissions that have not been - declared if building a base module. - -1.30.3 2006-03-28 - * Fixed checkmodule to call link_modules prior to expand_module - to handle optionals. - -1.30.2 2006-03-28 - * Fixed require_class to avoid shadowing permissions already defined - in an inherited common definition. - -1.30.1 2006-03-22 - * Moved processing of role and user require statements to 2nd pass. - -1.30 2006-03-14 - * Updated version for release. - -1.29.5 2006-03-09 - * Fixed bug in role dominance (define_role_dom). - -1.29.4 2006-02-14 - * Added a check for failure to declare each sensitivity in - a level definition. - -1.29.3 2006-02-13 - * Changed to clone level data for aliased sensitivities to - avoid double free upon sens_destroy. Bug reported by Kevin - Carr of Tresys Technology. - -1.29.2 2006-02-13 - * Merged optionals in base patch from Joshua Brindle. - -1.29.1 2006-02-01 - * Merged sepol_av_to_string patch from Joshua Brindle. - -1.28 2005-12-07 - * Updated version for release. - -1.27.20 2005-12-02 - * Merged checkmodule man page from Dan Walsh, and edited it. - -1.27.19 2005-12-01 - * Added error checking of all ebitmap_set_bit calls for out of - memory conditions. - -1.27.18 2005-12-01 - * Merged removal of compatibility handling of netlink classes - (requirement that policies with newer versions include the - netlink class definitions, remapping of fine-grained netlink - classes in newer source policies to single netlink class when - generating older policies) from George Coker. - -1.27.17 2005-10-25 - * Merged dismod fix from Joshua Brindle. - -1.27.16 2005-10-20 - * Removed obsolete cond_check_type_rules() function and call and - cond_optimize_lists() call from checkpolicy.c; these are handled - during parsing and expansion now. - -1.27.15 2005-10-19 - * Updated calls to expand_module for interface change. - -1.27.14 2005-10-19 - * Changed checkmodule to verify that expand_module succeeds - when building base modules. - -1.27.13 2005-10-19 - * Merged module compiler fixes from Joshua Brindle. - -1.27.12 2005-10-19 - * Removed direct calls to hierarchy_check_constraints() and - check_assertions() from checkpolicy since they are now called - internally by expand_module(). - -1.27.11 2005-10-18 - * Updated for changes to sepol policydb_index_others interface. - -1.27.10 2005-10-17 - * Updated for changes to sepol expand_module and link_modules interfaces. - -1.27.9 2005-10-13 - * Merged support for require blocks inside conditionals from - Joshua Brindle (Tresys). - -1.27.8 2005-10-06 - * Updated for changes to libsepol. - -1.27.7 2005-10-05 - * Merged several bug fixes from Joshua Brindle (Tresys). - -1.27.6 2005-10-03 - * Merged MLS in modules patch from Joshua Brindle (Tresys). - -1.27.5 2005-09-28 - * Merged error handling improvement in checkmodule from Karl MacMillan (Tresys). - -1.27.4 2005-09-26 - * Merged bugfix for dup role transition error messages from - Karl MacMillan (Tresys). - -1.27.3 2005-09-23 - * Merged policyver/modulever patches from Joshua Brindle (Tresys). - -1.27.2 2005-09-20 - * Fixed parse_categories handling of undefined category. - -1.27.1 2005-09-16 - * Merged bug fix for role dominance handling from Darrel Goeddel (TCS). - -1.26 2005-09-06 - * Updated version for release. - -1.25.12 2005-08-22 - * Fixed handling of validatetrans constraint expressions. - Bug reported by Dan Walsh for checkpolicy -M. - -1.25.11 2005-08-18 - * Merged use-after-free fix from Serge Hallyn (IBM). - Bug found by Coverity. - -1.25.10 2005-08-15 - * Fixed further memory leaks found by valgrind. - -1.25.9 2005-08-15 - * Changed checkpolicy to destroy the policydbs prior to exit - to allow leak detection. - * Fixed several memory leaks found by valgrind. - -1.25.8 2005-08-11 - * Updated checkpolicy and dispol for the new avtab format. - Converted users of ebitmaps to new inline operators. - Note: The binary policy format version has been incremented to - version 20 as a result of these changes. To build a policy - for a kernel that does not yet include these changes, use - the -c 19 option to checkpolicy. - -1.25.7 2005-08-11 - * Merged patch to prohibit use of "self" as a type name from Jason Tang (Tresys). - -1.25.6 2005-08-10 - * Merged patch to fix dismod compilation from Joshua Brindle (Tresys). - -1.25.5 2005-08-09 - * Fixed call to hierarchy checking code to pass the right policydb. - -1.25.4 2005-08-02 - * Merged patch to update dismod for the relocation of the - module read/write code from libsemanage to libsepol, and - to enable build of test subdirectory from Jason Tang (Tresys). - -1.25.3 2005-07-18 - * Merged hierarchy check fix from Joshua Brindle (Tresys). - -1.25.2 2005-07-06 - * Merged loadable module support from Tresys Technology. - -1.25.1 2005-06-24 - * Merged patch to prohibit the use of * and ~ in type sets - (other than in neverallow statements) and in role sets - from Joshua Brindle (Tresys). - -1.24 2005-06-20 - * Updated version for release. - -1.23.4 2005-05-19 - * Merged cleanup patch from Dan Walsh. - -1.23.3 2005-05-13 - * Added sepol_ prefix to Flask types to avoid namespace - collision with libselinux. - -1.23.2 2005-04-29 - * Merged identifier fix from Joshua Brindle (Tresys). - -1.23.1 2005-04-13 - * Merged hierarchical type/role patch from Tresys Technology. - * Merged MLS fixes from Darrel Goeddel of TCS. - -1.22 2005-03-09 - * Updated version for release. - -1.21.4 2005-02-17 - * Moved genpolusers utility to libsepol. - * Merged range_transition support from Darrel Goeddel (TCS). - -1.21.3 2005-02-16 - * Merged define_user() cleanup patch from Darrel Goeddel (TCS). - -1.21.2 2005-02-09 - * Changed relabel Makefile target to use restorecon. - -1.21.1 2005-01-26 - * Merged enhanced MLS support from Darrel Goeddel (TCS). - -1.20 2005-01-04 - * Merged typeattribute statement patch from Darrel Goeddel of TCS. - * Changed genpolusers to handle multiple user config files. - * Merged nodecon ordering patch from Chad Hanson of TCS. - -1.18 2004-10-07 - * MLS build fix. - * Fixed Makefile dependencies (Chris PeBenito). - * Merged fix for role dominance ordering issue from Chad Hanson of TCS. - * Preserve portcon ordering and apply more checking. - -1.16 2004-08-13 - * Allow empty conditional clauses. - * Moved genpolbools utility to libsepol. - * Updated for libsepol set functions. - * Changed to link with libsepol.a. - * Moved core functionality into libsepol. - * Merged bug fix for conditional self handling from Karl MacMillan, Dave Caplan, and Joshua Brindle of Tresys. - * Added genpolusers program. - * Fixed bug in checkpolicy conditional code. - -1.14 2004-06-28 - * Merged fix for MLS logic from Daniel Thayer of TCS. - * Require semicolon terminator for typealias statement. - -1.12 2004-06-16 - * Merged fine-grained netlink class support. - -1.10 2004-04-07 - * Merged ipv6 support from James Morris of RedHat. - * Fixed compute_av bug discovered by Chad Hanson of TCS. - -1.8 2004-03-09 - * Merged policydb MLS patch from Chad Hanson of TCS. - * Fixed mmap of policy file. - -1.6 2004-02-18 - * Merged conditional policy extensions from Tresys Technology. - * Added typealias declaration support per Russell Coker's request. - * Added support for excluding types from type sets based on - a patch by David Caplan, but reimplemented as a change to the - policy grammar. - * Merged patch from Colin Walters to report source file name and line - number for errors when available. - * Un-deprecated role transitions. - -1.4 2003-12-01 - * Regenerated headers. - * Merged patches from Bastian Blank and Joerg Hoh. - -1.2 2003-09-30 - * Merged MLS build patch from Karl MacMillan of Tresys. - * Merged checkpolicy man page from Magosanyi Arpad. - -1.1 2003-08-13 - * Fixed endian bug in policydb_write for behavior value. - * License -> GPL. - * Merged coding style cleanups from James Morris. - -1.0 2003-07-11 - * Initial public release. - Copied: tags/checkpolicy_1_30_12/checkpolicy/ChangeLog (from rev 2034, trunk/checkpolicy/ChangeLog) =================================================================== --- tags/checkpolicy_1_30_12/checkpolicy/ChangeLog (rev 0) +++ tags/checkpolicy_1_30_12/checkpolicy/ChangeLog 2006-09-28 12:16:58 UTC (rev 2035) @@ -0,0 +1,289 @@ +1.30.12 2006-09-28 + * Merged user and range_transition support for modules from + Darrel Goeddel + +1.30.11 2006-09-05 + * merged range_transition enhancements and user module format + changes from Darrel Goeddel + +1.30.10 2006-08-03 + * Merged symtab datum patch from Karl MacMillan. + +1.30.9 2006-06-29 + * Lindent. + +1.30.8 2006-06-29 + * Merged patch to remove TE rule conflict checking from the parser + from Joshua Brindle. This can only be done properly by the + expander. + +1.30.7 2006-06-27 + * Merged patch to make checkpolicy/checkmodule handling of + duplicate/conflicting TE rules the same as the expander + from Joshua Brindle. + +1.30.6 2006-06-26 + * Merged optionals in base take 2 patch set from Joshua Brindle. + +1.30.5 2006-05-05 + * Merged compiler cleanup patch from Karl MacMillan. + * Merged fix warnings patch from Karl MacMillan. + +1.30.4 2006-04-05 + * Changed require_class to reject permissions that have not been + declared if building a base module. + +1.30.3 2006-03-28 + * Fixed checkmodule to call link_modules prior to expand_module + to handle optionals. + +1.30.2 2006-03-28 + * Fixed require_class to avoid shadowing permissions already defined + in an inherited common definition. + +1.30.1 2006-03-22 + * Moved processing of role and user require statements to 2nd pass. + +1.30 2006-03-14 + * Updated version for release. + +1.29.5 2006-03-09 + * Fixed bug in role dominance (define_role_dom). + +1.29.4 2006-02-14 + * Added a check for failure to declare each sensitivity in + a level definition. + +1.29.3 2006-02-13 + * Changed to clone level data for aliased sensitivities to + avoid double free upon sens_destroy. Bug reported by Kevin + Carr of Tresys Technology. + +1.29.2 2006-02-13 + * Merged optionals in base patch from Joshua Brindle. + +1.29.1 2006-02-01 + * Merged sepol_av_to_string patch from Joshua Brindle. + +1.28 2005-12-07 + * Updated version for release. + +1.27.20 2005-12-02 + * Merged checkmodule man page from Dan Walsh, and edited it. + +1.27.19 2005-12-01 + * Added error checking of all ebitmap_set_bit calls for out of + memory conditions. + +1.27.18 2005-12-01 + * Merged removal of compatibility handling of netlink classes + (requirement that policies with newer versions include the + netlink class definitions, remapping of fine-grained netlink + classes in newer source policies to single netlink class when + generating older policies) from George Coker. + +1.27.17 2005-10-25 + * Merged dismod fix from Joshua Brindle. + +1.27.16 2005-10-20 + * Removed obsolete cond_check_type_rules() function and call and + cond_optimize_lists() call from checkpolicy.c; these are handled + during parsing and expansion now. + +1.27.15 2005-10-19 + * Updated calls to expand_module for interface change. + +1.27.14 2005-10-19 + * Changed checkmodule to verify that expand_module succeeds + when building base modules. + +1.27.13 2005-10-19 + * Merged module compiler fixes from Joshua Brindle. + +1.27.12 2005-10-19 + * Removed direct calls to hierarchy_check_constraints() and + check_assertions() from checkpolicy since they are now called + internally by expand_module(). + +1.27.11 2005-10-18 + * Updated for changes to sepol policydb_index_others interface. + +1.27.10 2005-10-17 + * Updated for changes to sepol expand_module and link_modules interfaces. + +1.27.9 2005-10-13 + * Merged support for require blocks inside conditionals from + Joshua Brindle (Tresys). + +1.27.8 2005-10-06 + * Updated for changes to libsepol. + +1.27.7 2005-10-05 + * Merged several bug fixes from Joshua Brindle (Tresys). + +1.27.6 2005-10-03 + * Merged MLS in modules patch from Joshua Brindle (Tresys). + +1.27.5 2005-09-28 + * Merged error handling improvement in checkmodule from Karl MacMillan (Tresys). + +1.27.4 2005-09-26 + * Merged bugfix for dup role transition error messages from + Karl MacMillan (Tresys). + +1.27.3 2005-09-23 + * Merged policyver/modulever patches from Joshua Brindle (Tresys). + +1.27.2 2005-09-20 + * Fixed parse_categories handling of undefined category. + +1.27.1 2005-09-16 + * Merged bug fix for role dominance handling from Darrel Goeddel (TCS). + +1.26 2005-09-06 + * Updated version for release. + +1.25.12 2005-08-22 + * Fixed handling of validatetrans constraint expressions. + Bug reported by Dan Walsh for checkpolicy -M. + +1.25.11 2005-08-18 + * Merged use-after-free fix from Serge Hallyn (IBM). + Bug found by Coverity. + +1.25.10 2005-08-15 + * Fixed further memory leaks found by valgrind. + +1.25.9 2005-08-15 + * Changed checkpolicy to destroy the policydbs prior to exit + to allow leak detection. + * Fixed several memory leaks found by valgrind. + +1.25.8 2005-08-11 + * Updated checkpolicy and dispol for the new avtab format. + Converted users of ebitmaps to new inline operators. + Note: The binary policy format version has been incremented to + version 20 as a result of these changes. To build a policy + for a kernel that does not yet include these changes, use + the -c 19 option to checkpolicy. + +1.25.7 2005-08-11 + * Merged patch to prohibit use of "self" as a type name from Jason Tang (Tresys). + +1.25.6 2005-08-10 + * Merged patch to fix dismod compilation from Joshua Brindle (Tresys). + +1.25.5 2005-08-09 + * Fixed call to hierarchy checking code to pass the right policydb. + +1.25.4 2005-08-02 + * Merged patch to update dismod for the relocation of the + module read/write code from libsemanage to libsepol, and + to enable build of test subdirectory from Jason Tang (Tresys). + +1.25.3 2005-07-18 + * Merged hierarchy check fix from Joshua Brindle (Tresys). + +1.25.2 2005-07-06 + * Merged loadable module support from Tresys Technology. + +1.25.1 2005-06-24 + * Merged patch to prohibit the use of * and ~ in type sets + (other than in neverallow statements) and in role sets + from Joshua Brindle (Tresys). + +1.24 2005-06-20 + * Updated version for release. + +1.23.4 2005-05-19 + * Merged cleanup patch from Dan Walsh. + +1.23.3 2005-05-13 + * Added sepol_ prefix to Flask types to avoid namespace + collision with libselinux. + +1.23.2 2005-04-29 + * Merged identifier fix from Joshua Brindle (Tresys). + +1.23.1 2005-04-13 + * Merged hierarchical type/role patch from Tresys Technology. + * Merged MLS fixes from Darrel Goeddel of TCS. + +1.22 2005-03-09 + * Updated version for release. + +1.21.4 2005-02-17 + * Moved genpolusers utility to libsepol. + * Merged range_transition support from Darrel Goeddel (TCS). + +1.21.3 2005-02-16 + * Merged define_user() cleanup patch from Darrel Goeddel (TCS). + +1.21.2 2005-02-09 + * Changed relabel Makefile target to use restorecon. + +1.21.1 2005-01-26 + * Merged enhanced MLS support from Darrel Goeddel (TCS). + +1.20 2005-01-04 + * Merged typeattribute statement patch from Darrel Goeddel of TCS. + * Changed genpolusers to handle multiple user config files. + * Merged nodecon ordering patch from Chad Hanson of TCS. + +1.18 2004-10-07 + * MLS build fix. + * Fixed Makefile dependencies (Chris PeBenito). + * Merged fix for role dominance ordering issue from Chad Hanson of TCS. + * Preserve portcon ordering and apply more checking. + +1.16 2004-08-13 + * Allow empty conditional clauses. + * Moved genpolbools utility to libsepol. + * Updated for libsepol set functions. + * Changed to link with libsepol.a. + * Moved core functionality into libsepol. + * Merged bug fix for conditional self handling from Karl MacMillan, Dave Caplan, and Joshua Brindle of Tresys. + * Added genpolusers program. + * Fixed bug in checkpolicy conditional code. + +1.14 2004-06-28 + * Merged fix for MLS logic from Daniel Thayer of TCS. + * Require semicolon terminator for typealias statement. + +1.12 2004-06-16 + * Merged fine-grained netlink class support. + +1.10 2004-04-07 + * Merged ipv6 support from James Morris of RedHat. + * Fixed compute_av bug discovered by Chad Hanson of TCS. + +1.8 2004-03-09 + * Merged policydb MLS patch from Chad Hanson of TCS. + * Fixed mmap of policy file. + +1.6 2004-02-18 + * Merged conditional policy extensions from Tresys Technology. + * Added typealias declaration support per Russell Coker's request. + * Added support for excluding types from type sets based on + a patch by David Caplan, but reimplemented as a change to the + policy grammar. + * Merged patch from Colin Walters to report source file name and line + number for errors when available. + * Un-deprecated role transitions. + +1.4 2003-12-01 + * Regenerated headers. + * Merged patches from Bastian Blank and Joerg Hoh. + +1.2 2003-09-30 + * Merged MLS build patch from Karl MacMillan of Tresys. + * Merged checkpolicy man page from Magosanyi Arpad. + +1.1 2003-08-13 + * Fixed endian bug in policydb_write for behavior value. + * License -> GPL. + * Merged coding style cleanups from James Morris. + +1.0 2003-07-11 + * Initial public release. + Deleted: tags/checkpolicy_1_30_12/checkpolicy/VERSION =================================================================== --- trunk/checkpolicy/VERSION 2006-09-18 19:13:13 UTC (rev 2032) +++ tags/checkpolicy_1_30_12/checkpolicy/VERSION 2006-09-28 12:16:58 UTC (rev 2035) @@ -1 +0,0 @@ -1.30.11 Copied: tags/checkpolicy_1_30_12/checkpolicy/VERSION (from rev 2034, trunk/checkpolicy/VERSION) =================================================================== --- tags/checkpolicy_1_30_12/checkpolicy/VERSION (rev 0) +++ tags/checkpolicy_1_30_12/checkpolicy/VERSION 2006-09-28 12:16:58 UTC (rev 2035) @@ -0,0 +1 @@ +1.30.12 Deleted: tags/checkpolicy_1_30_12/checkpolicy/module_compiler.c =================================================================== --- trunk/checkpolicy/module_compiler.c 2006-09-18 19:13:13 UTC (rev 2032) +++ tags/checkpolicy_1_30_12/checkpolicy/module_compiler.c 2006-09-28 12:16:58 UTC (rev 2035) @@ -1,1304 +0,0 @@ -/* Author : Joshua Brindle <jbr...@tr...> - * Karl MacMillan <kma...@tr...> - * Jason Tang <jt...@tr...> - * Added support for binary policy modules - * - * Copyright (C) 2004 - 2005 Tresys Technology, LLC - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2. - */ - -#include <assert.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> - -#include <sepol/policydb/policydb.h> -#include <sepol/policydb/avrule_block.h> -#include <sepol/policydb/conditional.h> - -#include "queue.h" -#include "module_compiler.h" - -union stack_item_u { - avrule_block_t *avrule; - cond_list_t *cond_list; -}; - -typedef struct scope_stack { - union stack_item_u u; - int type; /* for above union: 1 = avrule block, 2 = conditional */ - avrule_decl_t *decl; /* if in an avrule block, which - * declaration is current */ - avrule_t *last_avrule; - int in_else; /* if in an avrule block, within ELSE branch */ - int require_given; /* 1 if this block had at least one require */ - struct scope_stack *parent, *child; -} scope_stack_t; - -extern policydb_t *policydbp; -extern queue_t id_queue; -extern int yyerror(char *msg); -extern void yyerror2(char *fmt, ...); - -static int push_stack(int stack_type, ...); -static void pop_stack(void); - -/* keep track of the last item added to the stack */ -static scope_stack_t *stack_top = NULL; -static avrule_block_t *last_block; -static uint32_t next_decl_id = 1; - -int define_policy(int pass, int module_header_given) -{ - char *id; - - if (module_header_given) { - if (policydbp->policy_type != POLICY_MOD) { - yyerror - ("Module specification found while not building a policy module.\n"); - return -1; - } - - if (pass == 2) { - while ((id = queue_remove(id_queue)) != NULL) - free(id); - } else { - id = (char *)queue_remove(id_queue); - if (!id) { - yyerror("no module name"); - return -1; - } - policydbp->name = id; - if ((policydbp->version = - queue_remove(id_queue)) == NULL) { - yyerror - ("Expected a module version but none was found."); - return -1; - } - } - } else { - if (policydbp->policy_type == POLICY_MOD) { - yyerror - ("Building a policy module, but no module specification found.\n"); - return -1; - } - } - /* the first declaration within the global avrule - block will always have an id of 1 */ - next_decl_id = 2; - - /* reset the scoping stack */ - while (stack_top != NULL) { - pop_stack(); - } - if (push_stack(1, policydbp->global, policydbp->global->branch_list) == - -1) { - return -1; - } - last_block = policydbp->global; - return 0; -} - -/* Given the current parse stack, returns 1 if a declaration would be - * allowed here or 0 if not. For example, declarations are not - * allowed in conditionals, so if there are any conditionals in the - * current scope stack then this would return a 0. - */ -static int is_declaration_allowed(void) -{ - if (stack_top->type != 1 || stack_top->in_else) { - return 0; - } - return 1; -} - -/* Attempt to declare a symbol within the current declaration. If - * currently within a non-conditional and in a non-else branch then - * insert the symbol, return 0 on success if symbol was undeclared. - * For roles and users, it is legal to have multiple declarations; as - * such return 1 to indicate that caller must free() the datum because - * it was not added. If symbols may not be declared here return -1. - * For duplicate declarations return -2. For all else, including out - * of memory, return -3. Note that dest_value and datum_value might - * not be restricted pointers. */ -int declare_symbol(uint32_t symbol_type, - hashtab_key_t key, hashtab_datum_t datum, - uint32_t * dest_value, uint32_t * datum_value) -{ - avrule_decl_t *decl = stack_top->decl; - int retval; - - /* first check that symbols may be declared here */ - if (!is_declaration_allowed()) { - return -1; - } - retval = symtab_insert(policydbp, symbol_type, key, datum, - SCOPE_DECL, decl->decl_id, dest_value); - if (retval == 1) { - symtab_datum_t *s = - (symtab_datum_t *) hashtab_search(policydbp-> - symtab[symbol_type].table, - key); - assert(s != NULL); - *dest_value = s->value; - } else if (retval == -2) { - return -2; - } else if (retval < 0) { - return -3; - } else { /* fall through possible if retval is 0 */ - } - if (datum_value != NULL) { - if (ebitmap_set_bit(decl->declared.scope + symbol_type, - *datum_value - 1, 1)) { - return -3; - } - } - return retval; -} - -role_datum_t *declare_role(void) -{ - char *id = queue_remove(id_queue), *dest_id = NULL; - role_datum_t *role = NULL, *dest_role = NULL; - int retval; - uint32_t value; - - if (id == NULL) { - yyerror("no role name"); - return NULL; - } - if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) { - yyerror("Out of memory!"); - free(id); - return NULL; - } - role_datum_init(role); - - retval = - declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, - &value); - if (retval == 0) { - role->s.value = value; - if ((dest_id = strdup(id)) == NULL) { - yyerror("Out of memory!"); - return NULL; - } - } else { - /* this role was already declared in this module, or error */ - dest_id = id; - role_datum_destroy(role); - free(role); - } - if (retval == 0 || retval == 1) { - /* create a new role_datum_t for this decl, if necessary */ - hashtab_t roles_tab; - assert(stack_top->type == 1); - if (stack_top->parent == NULL) { - /* in parent, so use global symbol table */ - roles_tab = policydbp->p_roles.table; - } else { - roles_tab = stack_top->decl->p_roles.table; - } - dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id); - if (dest_role == NULL) { - if ((dest_role = - (role_datum_t *) malloc(sizeof(*dest_role))) == - NULL) { - yyerror("Out of memory!"); - free(dest_id); - return NULL; - } - role_datum_init(dest_role); - dest_role->s.value = value; - if (hashtab_insert(roles_tab, dest_id, dest_role)) { - yyerror("Out of memory!"); - free(dest_id); - role_datum_destroy(dest_role); - free(dest_role); - return NULL; - } - } else { - free(dest_id); - } - } else { - free(dest_id); - } - switch (retval) { - case -3:{ - yyerror("Out of memory!"); - return NULL; - } - case -2:{ - yyerror("duplicate declaration of role"); - return NULL; - } - case -1:{ - yyerror("could not declare role here"); - return NULL; - } - case 0:{ - if (ebitmap_set_bit - (&dest_role->dominates, role->s.value - 1, 1)) { - yyerror("out of memory"); - return NULL; - } - return dest_role; - } - case 1:{ - return dest_role; /* role already declared for this block */ - } - default:{ - assert(0); /* should never get here */ - } - } -} - -type_datum_t *declare_type(unsigned char primary, unsigned char isattr) -{ - char *id; - type_datum_t *typdatum; - int retval; - uint32_t value = 0; - - id = (char *)queue_remove(id_queue); - if (!id) { - yyerror("no type/attribute name?"); - return NULL; - } - if (strcmp(id, "self") == 0) { - yyerror - ("'self' is a reserved type name and may not be declared."); - free(id); - return NULL; - } - - typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); - if (!typdatum) { - yyerror("Out of memory!"); - free(id); - return NULL; - } - type_datum_init(typdatum); - typdatum->primary = primary; - typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; - - retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value); - if (retval == 0 || retval == 1) { - if (typdatum->primary) { - typdatum->s.value = value; - } - } else { - /* error occurred (can't have duplicate type declarations) */ - free(id); - type_datum_destroy(typdatum); - free(typdatum); - } - switch (retval) { - case -3:{ - yyerror("Out of memory!"); - return NULL; - } - case -2:{ - yyerror2("duplicate declaration of type/attribute"); - return NULL; - } - case -1:{ - yyerror("could not declare type/attribute here"); - return NULL; - } - case 0: - case 1:{ - return typdatum; - } - default:{ - assert(0); /* should never get here */ - } - } -} - -user_datum_t *declare_user(void) -{ - char *id = queue_remove(id_queue), *dest_id = NULL; - user_datum_t *user = NULL, *dest_user = NULL; - int retval; - uint32_t value = 0; - - if (id == NULL) { - yyerror("no user name"); - return NULL; - } - if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) { - yyerror("Out of memory!"); - free(id); - return NULL; - } - user_datum_init(user); - - retval = - declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value, - &value); - - if (retval == 0) { - user->s.value = value; - if ((dest_id = strdup(id)) == NULL) { - yyerror("Out of memory!"); - return NULL; - } - } else { - /* this user was already declared in this module, or error */ - dest_id = id; - user_datum_destroy(user); - free(user); - } - if (retval == 0 || retval == 1) { - /* create a new user_datum_t for this decl, if necessary */ - hashtab_t users_tab; - assert(stack_top->type == 1); - if (stack_top->parent == NULL) { - /* in parent, so use global symbol table */ - users_tab = policydbp->p_users.table; - } else { - users_tab = stack_top->decl->p_users.table; - } - dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id); - if (dest_user == NULL) { - if ((dest_user = - (user_datum_t *) malloc(sizeof(*dest_user))) == - NULL) { - yyerror("Out of memory!"); - free(dest_id); - return NULL; - } - user_datum_init(dest_user); - dest_user->s.value = value; - if (hashtab_insert(users_tab, dest_id, dest_user)) { - yyerror("Out of memory!"); - free(dest_id); - user_datum_destroy(dest_user); - free(dest_user); - return NULL; - } - } else { - free(dest_id); - } - } else { - free(dest_id); - } - switch (retval) { - case -3:{ - yyerror("Out of memory!"); - return NULL; - } - case -2:{ - yyerror("duplicate declaration of user"); - return NULL; - } - case -1:{ - yyerror("could not declare user here"); - return NULL; - } - case 0:{ - return dest_user; - } - case 1:{ - return dest_user; /* user already declared for this block */ - } - default:{ - assert(0); /* should never get here */ - } - } -} - -/* Return a type_datum_t for the local avrule_decl with the given ID. - * If it does not exist, create one with the same value as 'value'. - * This function assumes that the ID is within scope. c.f., - * is_id_in_scope(). - * - * NOTE: this function usurps ownership of id afterwards. The caller - * shall not reference it nor free() it afterwards. - */ -type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr) -{ - type_datum_t *dest_typdatum; - hashtab_t types_tab; - assert(stack_top->type == 1); - if (stack_top->parent == NULL) { - /* in global, so use global symbol table */ - types_tab = policydbp->p_types.table; - } else { - types_tab = stack_top->decl->p_types.table; - } - dest_typdatum = hashtab_search(types_tab, id); - if (!dest_typdatum) { - dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); - if (dest_typdatum == NULL) { - free(id); - return NULL; - } - type_datum_init(dest_typdatum); - dest_typdatum->s.value = value; - dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; - dest_typdatum->primary = 1; - if (hashtab_insert(types_tab, id, dest_typdatum)) { - free(id); - type_datum_destroy(dest_typdatum); - free(dest_typdatum); - return NULL; - } - - } else { - free(id); - if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) { - return NULL; - } - } - return dest_typdatum; -} - -/* Given the current parse stack, returns 1 if a requirement would be - * allowed here or 0 if not. For example, the ELSE branch may never - * have its own requirements. - */ -static int is_require_allowed(void) -{ - if (stack_top->type == 1 && !stack_top->in_else) { - return 1; - } - return 0; -} - -/* Attempt to require a symbol within the current scope. If currently - * within an optional (and not its else branch), add the symbol to the - * required list. Return 0 on success, 1 if caller needs to free() - * datum. If symbols may not be declared here return -1. For duplicate - * declarations return -2. For all else, including out of memory, - * return -3.. Note that dest_value and datum_value might not be - * restricted pointers. - */ -int require_symbol(uint32_t symbol_type, - hashtab_key_t key, hashtab_datum_t datum, - uint32_t * dest_value, uint32_t * datum_value) -{ - avrule_decl_t *decl = stack_top->decl; - int retval; - - /* first check that symbols may be required here */ - if (!is_require_allowed()) { - return -1; - } - retval = symtab_insert(policydbp, symbol_type, key, datum, - SCOPE_REQ, decl->decl_id, dest_value); - if (retval == 1) { - symtab_datum_t *s = - (symtab_datum_t *) hashtab_search(policydbp-> - symtab[symbol_type].table, - key); - assert(s != NULL); - *dest_value = s->value; - } else if (retval == -2) { - /* ignore require statements if that symbol was - * previously declared and is in current scope */ - int prev_declaration_ok = 0; - if (is_id_in_scope(symbol_type, key)) { - if (symbol_type == SYM_TYPES) { - /* check that previous symbol has same - * type/attribute-ness */ - unsigned char new_isattr = - ((type_datum_t *) datum)->flavor; - type_datum_t *old_datum = - (type_datum_t *) hashtab_search(policydbp-> - symtab - [SYM_TYPES]. - table, key); - assert(old_datum != NULL); - unsigned char old_isattr = old_datum->flavor; - prev_declaration_ok = - (old_isattr == new_isattr ? 1 : 0); - } else { - prev_declaration_ok = 1; - } - } - if (prev_declaration_ok) { - /* ignore this require statement because it - * was already declared within my scope */ - stack_top->require_given = 1; - return 1; - } else { - /* previous declaration was not in scope or - * had a mismatched type/attribute, so - * generate an error */ - return -2; - } - } else if (retval < 0) { - return -3; - } else { /* fall through possible if retval is 0 or 1 */ - } - if (datum_value != NULL) { - if (ebitmap_set_bit(decl->required.scope + symbol_type, - *datum_value - 1, 1)) { - return -3; - } - } - stack_top->require_given = 1; - return retval; -} - -int add_perm_to_class(uint32_t perm_value, uint32_t class_value) -{ - avrule_decl_t *decl = stack_top->decl; - scope_index_t *scope; - - assert(perm_value >= 1); - assert(class_value >= 1); - scope = &decl->required; - if (class_value > scope->class_perms_len) { - int i; - ebitmap_t *new_map = realloc(scope->class_perms_map, - class_value * sizeof(*new_map)); - if (new_map == NULL) { - return -1; - } - scope->class_perms_map = new_map; - for (i = scope->class_perms_len; i < class_value; i++) { - ebitmap_init(scope->class_perms_map + i); - } - scope->class_perms_len = class_value; - } - if (ebitmap_set_bit(scope->class_perms_map + class_value - 1, - perm_value - 1, 1)) { - return -1; - } - return 0; -} - -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 void class_datum_destroy(class_datum_t * cladatum) -{ - if (cladatum != NULL) { - hashtab_map(cladatum->permissions.table, perm_destroy, NULL); - hashtab_destroy(cladatum->permissions.table); - free(cladatum); - } -} - -int require_class(int pass) -{ - char *class_id = queue_remove(id_queue); - char *perm_id = NULL; - class_datum_t *datum = NULL; - perm_datum_t *perm = NULL; - int ret; - - if (pass == 2) { - free(class_id); - while ((perm_id = queue_remove(id_queue)) != NULL) - free(perm_id); - return 0; - } - - /* first add the class if it is not already there */ - if (class_id == NULL) { - yyerror("no class name for class definition?"); - return -1; - } - - if ((datum = calloc(1, sizeof(*datum))) == NULL || - symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) { - yyerror("Out of memory!"); - goto cleanup; - } - ret = - require_symbol(SYM_CLASSES, class_id, datum, &datum->s.value, - &datum->s.value); - switch (ret) { - case -3:{ - yyerror("Out of memory!"); - free(class_id); - class_datum_destroy(datum); - goto cleanup; - } - case -2:{ - yyerror("duplicate declaration of class"); - free(class_id); - class_datum_destroy(datum); - goto cleanup; - } - case -1:{ - yyerror("could not require class here"); - free(class_id); - class_datum_destroy(datum); - goto cleanup; - } - case 0:{ - /* a new class was added; reindex everything */ - if (policydb_index_classes(policydbp)) { - yyerror("Out of memory!"); - goto cleanup; - } - break; - } - case 1:{ - class_datum_destroy(datum); - datum = - hashtab_search(policydbp->p_classes.table, - class_id); - assert(datum); /* the class datum should have existed */ - free(class_id); - break; - } - default:{ - assert(0); /* should never get here */ - } - } - - /* now add each of the permissions to this class's requirements */ - while ((perm_id = queue_remove(id_queue)) != NULL) { - int allocated = 0; - - /* Is the permission already in the table? */ - perm = hashtab_search(datum->permissions.table, perm_id); - if (!perm && datum->comdatum) - perm = - hashtab_search(datum->comdatum->permissions.table, - perm_id); - if (perm) { - /* Yes, drop the name. */ - free(perm_id); - } else { - /* No - allocate and insert an entry for it. */ - if (policydbp->policy_type == POLICY_BASE) { - yyerror2 - ("Base policy - require of permission %s without prior declaration.", - perm_id); - free(perm_id); - goto cleanup; - } - allocated = 1; - if ((perm = malloc(sizeof(*perm))) == NULL) { - yyerror("Out of memory!"); - free(perm_id); - goto cleanup; - } - memset(perm, 0, sizeof(*perm)); - ret = - hashtab_insert(datum->permissions.table, perm_id, - perm); - if (ret) { - yyerror("Out of memory!"); - free(perm_id); - free(perm); - goto cleanup; - } - perm->s.value = datum->permissions.nprim + 1; - } - - if (add_perm_to_class(perm->s.value, datum->s.value) == -1) { - yyerror("Out of memory!"); - goto cleanup; - } - - /* Update number of primitives if we allocated one. */ - if (allocated) - datum->permissions.nprim++; - } - return 0; - cleanup: - return -1; -} - -int require_role(int pass) -{ - char *id = queue_remove(id_queue); - role_datum_t *role = NULL; - int retval; - if (pass == 2) { - free(id); - return 0; - } - if (id == NULL) { - yyerror("no role name"); - return -1; - } - if ((role = malloc(sizeof(*role))) == NULL) { - free(id); - yyerror("Out of memory!"); - return -1; - } - role_datum_init(role); - retval = - require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, - &role->s.value, &role->s.value); - if (retval != 0) { - free(id); - role_datum_destroy(role); - free(role); - } - switch (retval) { - case -3:{ - yyerror("Out of memory!"); - return -1; - } - case -2:{ - yyerror("duplicate declaration of role"); - return -1; - } - case -1:{ - yyerror("could not require role here"); - return -1; - } - case 0:{ - /* all roles dominate themselves */ - if (ebitmap_set_bit - (&role->dominates, role->s.value - 1, 1)) { - yyerror("Out of memory"); - return -1; - } - return 0; - } - case 1:{ - return 0; /* role already required */ - } - default:{ - assert(0); /* should never get here */ - } - } -} - -static int require_type_or_attribute(int pass, unsigned char isattr) -{ - char *id = queue_remove(id_queue); - type_datum_t *type = NULL; - int retval; - if (pass == 2) { - free(id); - return 0; - } - if (id == NULL) { - yyerror("no type name"); - return -1; - } - if ((type = malloc(sizeof(*type))) == NULL) { - free(id); - yyerror("Out of memory!"); - return -1; - } - type_datum_init(type); - type->primary = 1; - type->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; - retval = - require_symbol(SYM_TYPES, id, (hashtab_datum_t *) type, - &type->s.value, &type->s.value); - if (retval != 0) { - free(id); - free(type); - } - switch (retval) { - case -3:{ - yyerror("Out of memory!"); - return -1; - } - case -2:{ - yyerror("duplicate declaration of type/attribute"); - return -1; - } - case -1:{ - yyerror("could not require type/attribute here"); - return -1; - } - case 0:{ - return 0; - } - case 1:{ - return 0; /* type already required */ - } - default:{ - assert(0); /* should never get here */ - } - } -} - -int require_type(int pass) -{ - return require_type_or_attribute(pass, 0); -} - -int require_attribute(int pass) -{ - return require_type_or_attribute(pass, 1); -} - -int require_user(int pass) -{ - char *id = queue_remove(id_queue); - user_datum_t *user = NULL; - int retval; - if (pass == 1) { - free(id); - return 0; - } - if (id == NULL) { - yyerror("no user name"); - return -1; - } - if ((user = malloc(sizeof(*user))) == NULL) { - free(id); - yyerror("Out of memory!"); - return -1; - } - user_datum_init(user); - retval = - require_symbol(SYM_USERS, id, (hashtab_datum_t *) user, - &user->s.value, &user->s.value); - if (retval != 0) { - free(id); - user_datum_destroy(user); - } - switch (retval) { - case -3:{ - yyerror("Out of memory!"); - return -1; - } - case -2:{ - yyerror("duplicate declaration of user"); - return -1; - } - case -1:{ - yyerror("could not require user here"); - return -1; - } - case 0:{ - return 0; - } - case 1:{ - return 0; /* user already required */ - } - default:{ - assert(0); /* should never get here */ - } - } -} - -int require_bool(int pass) -{ - char *id = queue_remove(id_queue); - cond_bool_datum_t *booldatum = NULL; - int retval; - if (pass == 2) { - free(id); - return 0; - } - if (id == NULL) { - yyerror("no boolean name"); - return -1; - } - if ((booldatum = calloc(1, sizeof(*booldatum))) == NULL) { - cond_destroy_bool(id, booldatum, NULL); - yyerror("Out of memory!"); - return -1; - } - retval = - require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum, - &booldatum->s.value, &booldatum->s.value); - if (retval != 0) { - cond_destroy_bool(id, booldatum, NULL); - } - switch (retval) { - case -3:{ - yyerror("Out of memory!"); - return -1; - } - case -2:{ - yyerror("duplicate declaration of boolean"); - return -1; - } - case -1:{ - yyerror("could not require boolean here"); - return -1; - } - case 0:{ - return 0; - } - case 1:{ - return 0; /* boolean already required */ - } - default:{ - assert(0); /* should never get here */ - } - } -} - -static int is_scope_in_stack(scope_datum_t * scope, scope_stack_t * stack) -{ - int i; - if (stack == NULL) { - return 0; /* no matching scope found */ - } - if (stack->type == 1) { - avrule_decl_t *decl = stack->decl; - for (i = 0; i < scope->decl_ids_len; i++) { - if (scope->decl_ids[i] == decl->decl_id) { - return 1; - } - } - } else { - /* note that conditionals can't declare or require - * symbols, so skip this level */ - } - - /* not within scope of this stack, so try its parent */ - return is_scope_in_stack(scope, stack->parent); -} - -int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id) -{ - scope_datum_t *scope = - (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type]. - table, id); - if (scope == NULL) { - return 1; /* id is not known, so return success */ - } - return is_scope_in_stack(scope, stack_top); -} - -static int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value, - scope_index_t * scope) -{ - if (class_value > scope->class_perms_len) { - return 1; - } - if (ebitmap_get_bit(scope->class_perms_map + class_value - 1, - perm_value - 1)) { - return 1; - } - return 0; -} - -static int is_perm_in_stack(uint32_t perm_value, uint32_t class_value, - scope_stack_t * stack) -{ - if (stack == NULL) { - return 0; /* no matching scope found */ - } - if (stack->type == 1) { - avrule_decl_t *decl = stack->decl; - if (is_perm_in_scope_index - (perm_value, class_value, &decl->required) - || is_perm_in_scope_index(perm_value, class_value, - &decl->declared)) { - return 1; - } - } else { - /* note that conditionals can't declare or require - * symbols, so skip this level */ - } - - /* not within scope of this stack, so try its parent */ - return is_perm_in_stack(perm_value, class_value, stack->parent); -} - -int is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id) -{ - class_datum_t *cladatum = - (class_datum_t *) hashtab_search(policydbp->p_classes.table, - class_id); - perm_datum_t *perdatum; - if (cladatum == NULL) { - return 1; - } - perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table, - perm_id); - if (perdatum == NULL) { - return 1; - } - return is_perm_in_stack(perdatum->s.value, cladatum->s.value, - stack_top); -} - -cond_list_t *get_current_cond_list(cond_list_t * cond) -{ - /* FIX ME: do something different here if in a nested - * conditional? */ - avrule_decl_t *decl = stack_top->decl; - return get_decl_cond_list(policydbp, decl, cond); -} - -/* Append the new conditional node to the existing ones. During - * expansion the list will be reversed -- i.e., the last AV rule will - * be the first one listed in the policy. This matches the behavior - * of the upstream compiler. */ -void append_cond_list(cond_list_t * cond) -{ - cond_list_t *old_cond = get_current_cond_list(cond); - avrule_t *tmp; - assert(old_cond != NULL); /* probably out of memory */ - if (old_cond->avtrue_list == NULL) { - old_cond->avtrue_list = cond->avtrue_list; - } else { - for (tmp = old_cond->avtrue_list; tmp->next != NULL; - tmp = tmp->next) ; - tmp->next = cond->avtrue_list; - } - if (old_cond->avfalse_list == NULL) { - old_cond->avfalse_list = cond->avfalse_list; - } else { - for (tmp = old_cond->avfalse_list; tmp->next != NULL; - tmp = tmp->next) ; - tmp->next = cond->avfalse_list; - } -} - -void append_avrule(avrule_t * avrule) -{ - avrule_decl_t *decl = stack_top->decl; - - /* currently avrules follow a completely different code path - * for handling avrules and compute types - * (define_cond_avrule_te_avtab, define_cond_compute_type); - * therefore there ought never be a conditional on top of the - * scope stack */ - assert(stack_top->type == 1); - - if (stack_top->last_avrule == NULL) { - decl->avrules = avrule; - } else { - stack_top->last_avrule->next = avrule; - } - stack_top->last_avrule = avrule; -} - -/* this doesn't actually append, but really prepends it */ -void append_role_trans(role_trans_rule_t * role_tr_rules) -{ - avrule_decl_t *decl = stack_top->decl; - - /* role transitions are not allowed within conditionals */ - assert(stack_top->type == 1); - - role_tr_rules->next = decl->role_tr_rules; - decl->role_tr_rules = role_tr_rules; -} - -/* this doesn't actually append, but really prepends it */ -void append_role_allow(role_allow_rule_t * role_allow_rules) -{ - avrule_decl_t *decl = stack_top->decl; - - /* role allows are not allowed within conditionals */ - assert(stack_top->type == 1); - - role_allow_rules->next = decl->role_allow_rules; - decl->role_allow_rules = role_allow_rules; -} - -/* this doesn't actually append, but really prepends it */ -void append_range_trans(range_trans_rule_t * range_tr_rules) -{ - avrule_decl_t *decl = stack_top->decl; - - /* range transitions are not allowed within conditionals */ - assert(stack_top->type == 1); - - range_tr_rules->next = decl->range_tr_rules; - decl->range_tr_rules = range_tr_rules; -} - -int begin_optional(int pass) -{ - avrule_block_t *block = NULL; - avrule_decl_t *decl; - if (pass == 1) { - /* allocate a new avrule block for this optional block */ - if ((block = avrule_block_create()) == NULL || - (decl = avrule_decl_create(next_decl_id)) == NULL) { - goto cleanup; - } - block->flags |= AVRULE_OPTIONAL; - block->branch_list = decl; - last_block->next = block; - } else { - /* select the next block from the chain built during pass 1 */ - block = last_block->next; - assert(block != NULL && - block->branch_list != NULL && - block->branch_list->decl_id == next_decl_id); - decl = block->branch_list; - } - if (push_stack(1, block, decl) == -1) { - goto cleanup; - } - stack_top->last_avrule = NULL; - last_block = block; - next_decl_id++; - return 0; - cleanup: - yyerror("Out of memory!"); - avrule_block_destroy(block); - return -1; -} - -int end_optional(int pass) -{ - /* once nested conditionals are allowed, do the stack unfolding here */ - pop_stack(); - return 0; -} - -int begin_optional_else(int pass) -{ - avrule_decl_t *decl; - assert(stack_top->type == 1 && stack_top->in_else == 0); - if (pass == 1) { - /* allocate a new declaration and add it to the - * current chain */ - if ((decl = avrule_decl_create(next_decl_id)) == NULL) { - yyerror("Out of memory!"); - return -1; - } - stack_top->decl->next = decl; - } else { - /* pick the (hopefully last) declaration of this - avrule block, built from pass 1 */ - decl = stack_top->decl->next; - assert(decl != NULL && - decl->next == NULL && decl->decl_id == next_decl_id); - } - stack_top->in_else = 1; - stack_top->decl = decl; - stack_top->last_avrule = NULL; - stack_top->require_given = 0; - next_decl_id++; - return 0; -} - -static int copy_requirements(avrule_decl_t * dest, scope_stack_t * stack) -{ - int i; - if (stack == NULL) { - return 0; - } - if (stack->type == 1) { - scope_index_t *src_scope = &stack->decl->required; - scope_index_t *dest_scope = &dest->required; - for (i = 0; i < SYM_NUM; i++) { - ebitmap_t *src_bitmap = &src_scope->scope[i]; - ebitmap_t *dest_bitmap = &dest_scope->scope[i]; - if (ebitmap_union(dest_bitmap, src_bitmap)) { - yyerror("Out of memory!"); - return -1; - } - } - /* now copy class permissions */ - if (src_scope->class_perms_len > dest_scope->class_perms_len) { - ebitmap_t *new_map = - realloc(dest_scope->class_perms_map, - src_scope->class_perms_len * - sizeof(*new_map)); - if (new_map == NULL) { - yyerror("Out of memory!"); - return -1; - } - dest_scope->class_perms_map = new_map; - for (i = dest_scope->class_perms_len; - i < src_scope->class_perms_len; i++) { - ebitmap_init(dest_scope->class_perms_map + i); - } - dest_scope->class_perms_len = - src_scope->class_perms_len; - } - for (i = 0; i < src_scope->class_perms_len; i++) { - ebitmap_t *src_bitmap = &src_scope->class_perms_map[i]; - ebitmap_t *dest_bitmap = - &dest_scope->class_perms_map[i]; - if (ebitmap_union(dest_bitmap, src_bitmap)) { - yyerror("Out of memory!"); - return -1; - } - } - } - return copy_requirements(dest, stack->parent); -} - -/* During pass 1, check that at least one thing was required within - * this block, for those places where a REQUIRED is necessary. During - * pass 2, have this block inherit its parents' requirements. Return - * 0 on success, -1 on failure. */ -int end_avrule_block(int pass) -{ - avrule_decl_t *decl = stack_top->decl; - assert(stack_top->type == 1); - if (pass == 2) { - /* this avrule_decl inherits all of its parents' - * requirements */ - if (copy_requirements(decl, stack_top->parent) == -1) { - return -1; - } - return 0; - } - if (!stack_top->in_else && !stack_top->require_given) { - if (policydbp->policy_type == POLICY_BASE - && stack_top->parent != NULL) { - /* if this is base no require should be in the global block */ - return 0; - } else { - /* non-ELSE branches must have at least one thing required */ - yyerror("This block has no require section."); - return -1; - } - } - return 0; -} - -/* Push a new scope on to the stack and update the 'last' pointer. - * Return 0 on success, -1 if out * of memory. */ -static int push_stack(int stack_type, ...) -{ - scope_stack_t *s = calloc(1, sizeof(*s)); - va_list ap; - if (s == NULL) { - return -1; - } - va_start(ap, stack_type); - switch (s->type = stack_type) { - case 1:{ - s->u.avrule = va_arg(ap, avrule_block_t *); - s->decl = va_arg(ap, avrule_decl_t *); - break; - } - case 2:{ - s->u.cond_list = va_arg(ap, cond_list_t *); - break; - } - default: - /* invalid stack type given */ - assert(0); - } - va_end(ap); - s->parent = stack_top; - s->child = NULL; - stack_top = s; - return 0; -} - -/* Pop off the most recently added from the stack. Update the 'last' - * pointer. */ -static void pop_stack(void) -{ - scope_stack_t *parent; - assert(stack_top != NULL); - parent = stack_top->parent; - if (parent != NULL) { - parent->child = NULL; - } - free(stack_top); - stack_top = parent; -} Copied: tags/checkpolicy_1_30_12/checkpolicy/module_compiler.c (from rev 2033, trunk/checkpolicy/module_compiler.c) =================================================================== --- tags/checkpolicy_1_30_12/checkpolicy/module_compiler.c (rev 0) +++ tags/checkpolicy_1_30_12/checkpolicy/module_compiler.c 2006-09-28 12:16:58 UTC (rev 2035) @@ -0,0 +1,1420 @@ +/* Author : Joshua Brindle <jbr...@tr...> + * Karl MacMillan <kma...@tr...> + * Jason Tang <jt...@tr...> + * Added support for binary policy modules + * + * Copyright (C) 2004 - 2005 Tresys Technology, LLC + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + */ + +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#include <sepol/policydb/policydb.h> +#include <sepol/policydb/avrule_block.h> +#include <sepol/policydb/conditional.h> + +#include "queue.h" +#include "module_compiler.h" + +union stack_item_u { + avrule_block_t *avrule; + cond_list_t *cond_list; +}; + +typedef struct scope_stack { + union stack_item_u u; + int type; /* for above union: 1 = avrule block, 2 = conditional */ + avrule_decl_t *decl; /* if in an avrule block, which + * declaration is current */ + avrule_t *last_avrule; + int in_else; /* if in an avrule block, within ELSE branch */ + int require_given; /* 1 if this block had at least one require */ + struct scope_stack *parent, *child; +} scope_stack_t; + +extern policydb_t *policydbp; +extern queue_t id_queue; +extern int yyerror(char *msg); +extern void yyerror2(char *fmt, ...); + +static int push_stack(int stack_type, ...); +static void pop_stack(void); + +/* keep track of the last item added to the stack */ +static scope_stack_t *stack_top = NULL; +static avrule_block_t *last_block; +static uint32_t next_decl_id = 1; + +int define_policy(int pass, int module_header_given) +{ + char *id; + + if (module_header_given) { + if (policydbp->policy_type != POLICY_MOD) { + yyerror + ("Module specification found while not building a policy module.\n"); + return -1; + } + + if (pass == 2) { + while ((id = queue_remove(id_queue)) != NULL) + free(id); + } else { + id = (char *)queue_remove(id_queue); + if (!id) { + yyerror("no module name"); + return -1; + } + policydbp->name = id; + if ((policydbp->version = + queue_remove(id_queue)) == NULL) { + yyerror + ("Expected a module version but none was found."); + return -1; + } + } + } else { + if (policydbp->policy_type == POLICY_MOD) { + yyerror + ("Building a policy module, but no module specification found.\n"); + return -1; + } + } + /* the first declaration within the global avrule + block will always have an id of 1 */ + next_decl_id = 2; + + /* reset the scoping stack */ + while (stack_top != NULL) { + pop_stack(); + } + if (push_stack(1, policydbp->global, policydbp->global->branch_list) == + -1) { + return -1; + } + last_block = policydbp->global; + return 0; +} + +/* Given the current parse stack, returns 1 if a declaration would be + * allowed here or 0 if not. For example, declarations are not + * allowed in conditionals, so if there are any conditionals in the + * current scope stack then this would return a 0. + */ +static int is_declaration_allowed(void) +{ + if (stack_top->type != 1 || stack_top->in_else) { + return 0; + } + return 1; +} + +/* Attempt to declare a symbol within the current declaration. If + * currently within a non-conditional and in a non-else branch then + * insert the symbol, return 0 on success if symbol was undeclared. + * For roles and users, it is legal to have multiple declarations; as + * such return 1 to indicate that caller must free() the datum because + * it was not added. If symbols may not be declared here return -1. + * For duplicate declarations return -2. For all else, including out + * of memory, return -3. Note that dest_value and datum_value might + * not be restricted pointers. */ +int declare_symbol(uint32_t symbol_type, + hashtab_key_t key, hashtab_datum_t datum, + uint32_t * dest_value, uint32_t * datum_value) +{ + avrule_decl_t *decl = stack_top->decl; + int retval; + + /* first check that symbols may be declared here */ + if (!is_declaration_allowed()) { + return -1; + } + retval = symtab_insert(policydbp, symbol_type, key, datum, + SCOPE_DECL, decl->decl_id, dest_value); + if (retval == 1) { + symtab_datum_t *s = + (symtab_datum_t *) hashtab_search(policydbp-> + symtab[symbol_type].table, + key); + assert(s != NULL); + *dest_value = s->value; + } else if (retval == -2) { + return -2; + } else if (retval < 0) { + return -3; + } else { /* fall through possible if retval is 0 */ + } + if (datum_value != NULL) { + if (ebitmap_set_bit(decl->declared.scope + symbol_type, + *datum_value - 1, 1)) { + return -3; + } + } + return retval; +} + +role_datum_t *declare_role(void) +{ + char *id = queue_remove(id_queue), *dest_id = NULL; + role_datum_t *role = NULL, *dest_role = NULL; + int retval; + uint32_t value; + + if (id == NULL) { + yyerror("no role name"); + return NULL; + } + if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) { + yyerror("Out of memory!"); + free(id); + return NULL; + } + role_datum_init(role); + + retval = + declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, + &value); + if (retval == 0) { + role->s.value = value; + if ((dest_id = strdup(id)) == NULL) { + yyerror("Out of memory!"); + return NULL; + } + } else { + /* this role was already declared in this module, or error */ + dest_id = id; + role_datum_destroy(role); + free(role); + } + if (retval == 0 || retval == 1) { + /* create a new role_datum_t for this decl, if necessary */ + hashtab_t roles_tab; + assert(stack_top->type == 1); + if (stack_top->parent == NULL) { + /* in parent, so use global symbol table */ + roles_tab = policydbp->p_roles.table; + } else { + roles_tab = stack_top->decl->p_roles.table; + } + dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id); + if (dest_role == NULL) { + if ((dest_role = + (role_datum_t *) malloc(sizeof(*dest_role))) == + NULL) { + yyerror("Out of memory!"); + free(dest_id); + return NULL; + } + role_datum_init(dest_role); + dest_role->s.value = value; + if (hashtab_insert(roles_tab, dest_id, dest_role)) { + yyerror("Out of memory!"); + free(dest_id); + role_datum_destroy(dest_role); + free(dest_role); + return NULL; + } + } else { + free(dest_id); + } + } else { + free(dest_id); + } + switch (retval) { + case -3:{ + yyerror("Out of memory!"); + return NULL; + } + case -2:{ + yyerror("duplicate declaration of role"); + return NULL; + } + case -1:{ + yyerror("could not declare role here"); + return NULL; + } + case 0:{ + if (ebitmap_set_bit + (&dest_role->dominates, role->s.value - 1, 1)) { + yyer... [truncated message content] |