summaryrefslogtreecommitdiffstats
path: root/libqpol/src/policy_parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'libqpol/src/policy_parse.y')
-rw-r--r--libqpol/src/policy_parse.y834
1 files changed, 834 insertions, 0 deletions
diff --git a/libqpol/src/policy_parse.y b/libqpol/src/policy_parse.y
new file mode 100644
index 0000000..84f4114
--- /dev/null
+++ b/libqpol/src/policy_parse.y
@@ -0,0 +1,834 @@
+/**
+ * @file policy_parse.y
+ *
+ * This file is based upon checkpolicy/policy_parse.y from NSA's SVN
+ * repository. It has been modified to support older policy formats.
+ */
+
+/*
+ * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+ */
+
+/*
+ * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
+ *
+ * Support for enhanced MLS infrastructure.
+ *
+ * Updated: David Caplan, <dac@tresys.com>
+ *
+ * Added conditional policy language extensions
+ *
+ * Updated: Joshua Brindle <jbrindle@tresys.com>
+ * Karl MacMillan <kmacmillan@mentalrootkit.com>
+ * Jason Tang <jtang@tresys.com>
+ *
+ * Added support for binary policy modules
+ *
+ * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
+ * Copyright (C) 2003 - 2008 Tresys Technology, LLC
+ * Copyright (C) 2007 Red Hat Inc.
+ * 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.
+ */
+
+/* FLASK */
+
+%{
+#include <config.h>
+
+#include <sys/types.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+
+#include <sepol/policydb/expand.h>
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/services.h>
+#include <sepol/policydb/conditional.h>
+#include <sepol/policydb/flask.h>
+#include <sepol/policydb/hierarchy.h>
+#ifdef HAVE_SEPOL_POLICYCAPS
+#include <sepol/policydb/polcaps.h>
+#endif
+
+#include "queue.h"
+#include <qpol/policy.h>
+#include "module_compiler.h"
+#include "policy_define.h"
+
+extern policydb_t *policydbp;
+extern unsigned int pass;
+
+extern char yytext[];
+extern int yylex(void);
+extern int yywarn(char *msg);
+extern int yyerror(char *msg);
+
+typedef int (* require_func_t)();
+
+/* redefine input so we can read from a string */
+/* borrowed from O'Reilly lex and yacc pg 157 */
+extern char qpol_src_input[];
+extern char *qpol_src_inputptr;/* current position in qpol_src_input */
+extern char *qpol_src_inputlim;/* end of data */
+
+%}
+
+%union {
+ unsigned int val;
+ uintptr_t valptr;
+ void *ptr;
+ require_func_t require_func;
+}
+
+%type <ptr> cond_expr cond_expr_prim cond_pol_list cond_else
+%type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def
+%type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def
+%type <ptr> role_def roles
+%type <valptr> cexpr cexpr_prim op role_mls_op
+%type <val> ipv4_addr_def number
+%type <require_func> require_decl_def
+
+%token PATH
+%token CLONE
+%token COMMON
+%token CLASS
+%token CONSTRAIN
+%token VALIDATETRANS
+%token INHERITS
+%token SID
+%token ROLE
+%token ROLES
+%token TYPEALIAS
+%token TYPEATTRIBUTE
+%token TYPEBOUNDS
+%token TYPE
+%token TYPES
+%token ALIAS
+%token ATTRIBUTE
+%token BOOL
+%token IF
+%token ELSE
+%token TYPE_TRANSITION
+%token TYPE_MEMBER
+%token TYPE_CHANGE
+%token ROLE_TRANSITION
+%token RANGE_TRANSITION
+%token SENSITIVITY
+%token DOMINANCE
+%token DOM DOMBY INCOMP
+%token CATEGORY
+%token LEVEL
+%token RANGE
+%token MLSCONSTRAIN
+%token MLSVALIDATETRANS
+%token USER
+%token NEVERALLOW
+%token ALLOW
+%token AUDITALLOW
+%token AUDITDENY
+%token DONTAUDIT
+%token SOURCE
+%token TARGET
+%token SAMEUSER
+%token FSCON PORTCON NETIFCON NODECON
+%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON
+%token FSUSEXATTR FSUSETASK FSUSETRANS FSUSEPSID
+%token GENFSCON
+%token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
+%token NOT AND OR XOR
+%token CTRUE CFALSE
+%token IDENTIFIER
+%token NUMBER
+%token EQUALS
+%token NOTEQUAL
+%token IPV4_ADDR
+%token IPV6_ADDR
+%token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
+%token POLICYCAP
+%token PERMISSIVE
+
+%left OR
+%left XOR
+%left AND
+%right NOT
+%left EQUALS NOTEQUAL
+%%
+policy : base_policy
+ | module_policy
+ ;
+base_policy : { if (define_policy(pass, 0) == -1) return -1; }
+ classes initial_sids access_vectors
+ { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; }
+ else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1; }}
+ opt_mls te_rbac users opt_constraints
+ { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
+ else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
+ initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
+ ;
+classes : class_def
+ | classes class_def
+ ;
+class_def : CLASS identifier
+ {if (define_class()) return -1;}
+ ;
+initial_sids : initial_sid_def
+ | initial_sids initial_sid_def
+ ;
+initial_sid_def : SID identifier
+ {if (define_initial_sid()) return -1;}
+ ;
+access_vectors : opt_common_perms av_perms
+ ;
+opt_common_perms : common_perms
+ |
+ ;
+common_perms : common_perms_def
+ | common_perms common_perms_def
+ ;
+common_perms_def : COMMON identifier '{' identifier_list '}'
+ {if (define_common_perms()) return -1;}
+ ;
+av_perms : av_perms_def
+ | av_perms av_perms_def
+ ;
+av_perms_def : CLASS identifier '{' identifier_list '}'
+ {if (define_av_perms(FALSE)) return -1;}
+ | CLASS identifier INHERITS identifier
+ {if (define_av_perms(TRUE)) return -1;}
+ | CLASS identifier INHERITS identifier '{' identifier_list '}'
+ {if (define_av_perms(TRUE)) return -1;}
+ ;
+opt_mls : mls
+ |
+ ;
+mls : sensitivities dominance opt_categories levels mlspolicy
+ ;
+sensitivities : sensitivity_def
+ | sensitivities sensitivity_def
+ ;
+/* Need to call define_mls here, as we are working with files */
+/* only, not command line options */
+sensitivity_def : SENSITIVITY identifier alias_def ';'
+ {if (define_mls() | define_sens()) return -1;}
+ | SENSITIVITY identifier ';'
+ {if (define_mls() | define_sens()) return -1;}
+ ;
+alias_def : ALIAS names
+ ;
+dominance : DOMINANCE identifier
+ {if (define_dominance()) return -1;}
+ | DOMINANCE '{' identifier_list '}'
+ {if (define_dominance()) return -1;}
+ ;
+opt_categories : categories
+ |
+ ;
+categories : category_def
+ | categories category_def
+ ;
+category_def : CATEGORY identifier alias_def ';'
+ {if (define_category()) return -1;}
+ | CATEGORY identifier ';'
+ {if (define_category()) return -1;}
+ ;
+levels : level_def
+ | levels level_def
+ ;
+level_def : LEVEL identifier ':' id_comma_list ';'
+ {if (define_level()) return -1;}
+ | LEVEL identifier ';'
+ {if (define_level()) return -1;}
+ ;
+mlspolicy : mlspolicy_decl
+ | mlspolicy mlspolicy_decl
+ ;
+mlspolicy_decl : mlsconstraint_def
+ | mlsvalidatetrans_def
+ ;
+mlsconstraint_def : MLSCONSTRAIN names names cexpr ';'
+ { if (define_constraint((constraint_expr_t*)$4)) return -1; }
+ ;
+mlsvalidatetrans_def : MLSVALIDATETRANS names cexpr ';'
+ { if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
+ ;
+te_rbac : te_rbac_decl
+ | te_rbac te_rbac_decl
+ ;
+te_rbac_decl : te_decl
+ | rbac_decl
+ | cond_stmt_def
+ | optional_block
+ | policycap_def
+ | ';'
+ ;
+rbac_decl : role_type_def
+ | role_dominance
+ | role_trans_def
+ | role_allow_def
+ ;
+te_decl : attribute_def
+ | type_def
+ | typealias_def
+ | typeattribute_def
+ | typebounds_def
+ | bool_def
+ | transition_def
+ | range_trans_def
+ | te_avtab_def
+ | permissive_def
+ ;
+attribute_def : ATTRIBUTE identifier ';'
+ { if (define_attrib()) return -1;}
+ ;
+type_def : TYPE identifier alias_def opt_attr_list ';'
+ {if (define_type(1)) return -1;}
+ | TYPE identifier opt_attr_list ';'
+ {if (define_type(0)) return -1;}
+ ;
+typealias_def : TYPEALIAS identifier alias_def ';'
+ {if (define_typealias()) return -1;}
+ ;
+typeattribute_def : TYPEATTRIBUTE identifier id_comma_list ';'
+ {if (define_typeattribute()) return -1;}
+ ;
+typebounds_def : TYPEBOUNDS identifier id_comma_list ';'
+ {if (define_typebounds()) return -1;}
+ ;
+opt_attr_list : ',' id_comma_list
+ |
+ ;
+bool_def : BOOL identifier bool_val ';'
+ {if (define_bool()) return -1;}
+ ;
+bool_val : CTRUE
+ { if (insert_id("T",0)) return -1; }
+ | CFALSE
+ { if (insert_id("F",0)) return -1; }
+ ;
+cond_stmt_def : IF cond_expr '{' cond_pol_list '}' cond_else
+ { if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (avrule_t*)$4, (avrule_t*)$6) < 0) return -1; }}
+ ;
+cond_else : ELSE '{' cond_pol_list '}'
+ { $$ = $3; }
+ | /* empty */
+ { $$ = NULL; }
+cond_expr : '(' cond_expr ')'
+ { $$ = $2;}
+ | NOT cond_expr
+ { $$ = define_cond_expr(COND_NOT, $2, 0);
+ if ($$ == 0) return -1; }
+ | cond_expr AND cond_expr
+ { $$ = define_cond_expr(COND_AND, $1, $3);
+ if ($$ == 0) return -1; }
+ | cond_expr OR cond_expr
+ { $$ = define_cond_expr(COND_OR, $1, $3);
+ if ($$ == 0) return -1; }
+ | cond_expr XOR cond_expr
+ { $$ = define_cond_expr(COND_XOR, $1, $3);
+ if ($$ == 0) return -1; }
+ | cond_expr EQUALS cond_expr
+ { $$ = define_cond_expr(COND_EQ, $1, $3);
+ if ($$ == 0) return -1; }
+ | cond_expr NOTEQUAL cond_expr
+ { $$ = define_cond_expr(COND_NEQ, $1, $3);
+ if ($$ == 0) return -1; }
+ | cond_expr_prim
+ { $$ = $1; }
+ ;
+cond_expr_prim : identifier
+ { $$ = define_cond_expr(COND_BOOL,0, 0);
+ if ($$ == COND_ERR) return -1; }
+ ;
+cond_pol_list : cond_pol_list cond_rule_def
+ { $$ = define_cond_pol_list((avrule_t *)$1, (avrule_t *)$2); }
+ | /* empty */
+ { $$ = NULL; }
+ ;
+cond_rule_def : cond_transition_def
+ { $$ = $1; }
+ | cond_te_avtab_def
+ { $$ = $1; }
+ | require_block
+ { $$ = NULL; }
+ ;
+cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';'
+ { $$ = define_cond_compute_type(AVRULE_TRANSITION) ;
+ if ($$ == COND_ERR) return -1;}
+ | TYPE_MEMBER names names ':' names identifier ';'
+ { $$ = define_cond_compute_type(AVRULE_MEMBER) ;
+ if ($$ == COND_ERR) return -1;}
+ | TYPE_CHANGE names names ':' names identifier ';'
+ { $$ = define_cond_compute_type(AVRULE_CHANGE) ;
+ if ($$ == COND_ERR) return -1;}
+ ;
+cond_te_avtab_def : cond_allow_def
+ { $$ = $1; }
+ | cond_auditallow_def
+ { $$ = $1; }
+ | cond_auditdeny_def
+ { $$ = $1; }
+ | cond_dontaudit_def
+ { $$ = $1; }
+ ;
+cond_allow_def : ALLOW names names ':' names names ';'
+ { $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
+ if ($$ == COND_ERR) return -1; }
+ ;
+cond_auditallow_def : AUDITALLOW names names ':' names names ';'
+ { $$ = define_cond_te_avtab(AVRULE_AUDITALLOW) ;
+ if ($$ == COND_ERR) return -1; }
+ ;
+cond_auditdeny_def : AUDITDENY names names ':' names names ';'
+ { $$ = define_cond_te_avtab(AVRULE_AUDITDENY) ;
+ if ($$ == COND_ERR) return -1; }
+ ;
+cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
+ { $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
+ if ($$ == COND_ERR) return -1; }
+ ;
+transition_def : TYPE_TRANSITION names names ':' names identifier ';'
+ {if (define_compute_type(AVRULE_TRANSITION)) return -1;}
+ | TYPE_MEMBER names names ':' names identifier ';'
+ {if (define_compute_type(AVRULE_MEMBER)) return -1;}
+ | TYPE_CHANGE names names ':' names identifier ';'
+ {if (define_compute_type(AVRULE_CHANGE)) return -1;}
+ ;
+range_trans_def : RANGE_TRANSITION names names mls_range_def ';'
+ { if (define_range_trans(0)) return -1; }
+ | RANGE_TRANSITION names names ':' names mls_range_def ';'
+ { if (define_range_trans(1)) return -1; }
+ ;
+te_avtab_def : allow_def
+ | auditallow_def
+ | auditdeny_def
+ | dontaudit_def
+ | neverallow_def
+ ;
+allow_def : ALLOW names names ':' names names ';'
+ {if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
+ ;
+auditallow_def : AUDITALLOW names names ':' names names ';'
+ {if (define_te_avtab(AVRULE_AUDITALLOW)) return -1; }
+ ;
+auditdeny_def : AUDITDENY names names ':' names names ';'
+ {if (define_te_avtab(AVRULE_AUDITDENY)) return -1; }
+ ;
+dontaudit_def : DONTAUDIT names names ':' names names ';'
+ {if (define_te_avtab(AVRULE_DONTAUDIT)) return -1; }
+ ;
+neverallow_def : NEVERALLOW names names ':' names names ';'
+ {if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
+ ;
+role_type_def : ROLE identifier TYPES names ';'
+ {if (define_role_types()) return -1;}
+ | ROLE identifier';'
+ {if (define_role_types()) return -1;}
+ ;
+role_dominance : DOMINANCE '{' roles '}'
+ ;
+role_trans_def : ROLE_TRANSITION names names identifier ';'
+ {if (define_role_trans()) return -1; }
+ ;
+role_allow_def : ALLOW names names ';'
+ {if (define_role_allow()) return -1; }
+ ;
+roles : role_def
+ { $$ = $1; }
+ | roles role_def
+ { $$ = merge_roles_dom((role_datum_t*)$1, (role_datum_t*)$2); if ($$ == 0) return -1;}
+ ;
+role_def : ROLE identifier_push ';'
+ {$$ = define_role_dom(NULL); if ($$ == 0) return -1;}
+ | ROLE identifier_push '{' roles '}'
+ {$$ = define_role_dom((role_datum_t*)$4); if ($$ == 0) return -1;}
+ ;
+opt_constraints : constraints
+ |
+ ;
+constraints : constraint_decl
+ | constraints constraint_decl
+ ;
+constraint_decl : constraint_def
+ | validatetrans_def
+ ;
+constraint_def : CONSTRAIN names names cexpr ';'
+ { if (define_constraint((constraint_expr_t*)$4)) return -1; }
+ ;
+validatetrans_def : VALIDATETRANS names cexpr ';'
+ { if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
+ ;
+cexpr : '(' cexpr ')'
+ { $$ = $2; }
+ | NOT cexpr
+ { $$ = define_cexpr(CEXPR_NOT, $2, 0);
+ if ($$ == 0) return -1; }
+ | cexpr AND cexpr
+ { $$ = define_cexpr(CEXPR_AND, $1, $3);
+ if ($$ == 0) return -1; }
+ | cexpr OR cexpr
+ { $$ = define_cexpr(CEXPR_OR, $1, $3);
+ if ($$ == 0) return -1; }
+ | cexpr_prim
+ { $$ = $1; }
+ ;
+cexpr_prim : U1 op U2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, $2);
+ if ($$ == 0) return -1; }
+ | R1 role_mls_op R2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
+ if ($$ == 0) return -1; }
+ | T1 op T2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_TYPE, $2);
+ if ($$ == 0) return -1; }
+ | U1 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, CEXPR_USER, $2);
+ if ($$ == 0) return -1; }
+ | U2 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_TARGET), $2);
+ if ($$ == 0) return -1; }
+ | U3 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_XTARGET), $2);
+ if ($$ == 0) return -1; }
+ | R1 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, $2);
+ if ($$ == 0) return -1; }
+ | R2 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), $2);
+ if ($$ == 0) return -1; }
+ | R3 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
+ if ($$ == 0) return -1; }
+ | T1 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
+ if ($$ == 0) return -1; }
+ | T2 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
+ if ($$ == 0) return -1; }
+ | T3 op { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
+ if ($$ == 0) return -1; }
+ | SAMEUSER
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, CEXPR_EQ);
+ if ($$ == 0) return -1; }
+ | SOURCE ROLE { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, CEXPR_EQ);
+ if ($$ == 0) return -1; }
+ | TARGET ROLE { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), CEXPR_EQ);
+ if ($$ == 0) return -1; }
+ | ROLE role_mls_op
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
+ if ($$ == 0) return -1; }
+ | SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
+ if ($$ == 0) return -1; }
+ | TARGET TYPE { if (insert_separator(1)) return -1; } names_push
+ { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
+ if ($$ == 0) return -1; }
+ | L1 role_mls_op L2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1L2, $2);
+ if ($$ == 0) return -1; }
+ | L1 role_mls_op H2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H2, $2);
+ if ($$ == 0) return -1; }
+ | H1 role_mls_op L2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1L2, $2);
+ if ($$ == 0) return -1; }
+ | H1 role_mls_op H2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1H2, $2);
+ if ($$ == 0) return -1; }
+ | L1 role_mls_op H1
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H1, $2);
+ if ($$ == 0) return -1; }
+ | L2 role_mls_op H2
+ { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L2H2, $2);
+ if ($$ == 0) return -1; }
+ ;
+op : EQUALS
+ { $$ = CEXPR_EQ; }
+ | NOTEQUAL
+ { $$ = CEXPR_NEQ; }
+ ;
+role_mls_op : op
+ { $$ = $1; }
+ | DOM
+ { $$ = CEXPR_DOM; }
+ | DOMBY
+ { $$ = CEXPR_DOMBY; }
+ | INCOMP
+ { $$ = CEXPR_INCOMP; }
+ ;
+users : user_def
+ | users user_def
+ ;
+user_def : USER identifier ROLES names opt_mls_user ';'
+ {if (define_user()) return -1;}
+ ;
+opt_mls_user : LEVEL mls_level_def RANGE mls_range_def
+ |
+ ;
+initial_sid_contexts : initial_sid_context_def
+ | initial_sid_contexts initial_sid_context_def
+ ;
+initial_sid_context_def : SID identifier security_context_def
+ {if (define_initial_sid_context()) return -1;}
+ ;
+opt_dev_contexts : dev_contexts |
+ ;
+dev_contexts : dev_context_def
+ | dev_contexts dev_context_def
+ ;
+dev_context_def : pirq_context_def |
+ iomem_context_def |
+ ioport_context_def |
+ pci_context_def
+ ;
+pirq_context_def : PIRQCON number security_context_def
+ {if (define_pirq_context($2)) return -1;}
+ ;
+iomem_context_def : IOMEMCON number security_context_def
+ {if (define_iomem_context($2,$2)) return -1;}
+ | IOMEMCON number '-' number security_context_def
+ {if (define_iomem_context($2,$4)) return -1;}
+ ;
+ioport_context_def : IOPORTCON number security_context_def
+ {if (define_ioport_context($2,$2)) return -1;}
+ | IOPORTCON number '-' number security_context_def
+ {if (define_ioport_context($2,$4)) return -1;}
+ ;
+pci_context_def : PCIDEVICECON number security_context_def
+ {if (define_pcidevice_context($2)) return -1;}
+ ;
+opt_fs_contexts : fs_contexts
+ |
+ ;
+fs_contexts : fs_context_def
+ | fs_contexts fs_context_def
+ ;
+fs_context_def : FSCON number number security_context_def security_context_def
+ {if (define_fs_context($2,$3)) return -1;}
+ ;
+net_contexts : opt_port_contexts opt_netif_contexts opt_node_contexts
+ ;
+opt_port_contexts : port_contexts
+ |
+ ;
+port_contexts : port_context_def
+ | port_contexts port_context_def
+ ;
+port_context_def : PORTCON identifier number security_context_def
+ {if (define_port_context($3,$3)) return -1;}
+ | PORTCON identifier number '-' number security_context_def
+ {if (define_port_context($3,$5)) return -1;}
+ ;
+opt_netif_contexts : netif_contexts
+ |
+ ;
+netif_contexts : netif_context_def
+ | netif_contexts netif_context_def
+ ;
+netif_context_def : NETIFCON identifier security_context_def security_context_def
+ {if (define_netif_context()) return -1;}
+ ;
+opt_node_contexts : node_contexts
+ |
+ ;
+node_contexts : node_context_def
+ | node_contexts node_context_def
+ ;
+node_context_def : NODECON ipv4_addr_def ipv4_addr_def security_context_def
+ {if (define_ipv4_node_context()) return -1;}
+ | NODECON ipv6_addr ipv6_addr security_context_def
+ {if (define_ipv6_node_context()) return -1;}
+ ;
+opt_fs_uses : fs_uses
+ |
+ ;
+fs_uses : fs_use_def
+ | fs_uses fs_use_def
+ ;
+fs_use_def : FSUSEXATTR identifier security_context_def ';'
+ {if (define_fs_use(SECURITY_FS_USE_XATTR)) return -1;}
+ | FSUSETASK identifier security_context_def ';'
+ {if (define_fs_use(SECURITY_FS_USE_TASK)) return -1;}
+ | FSUSETRANS identifier security_context_def ';'
+ {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
+ | FSUSEPSID identifier ';'
+ {if (define_fs_use(SECURITY_FS_USE_PSIDS)) return -1;}
+ ;
+opt_genfs_contexts : genfs_contexts
+ |
+ ;
+genfs_contexts : genfs_context_def
+ | genfs_contexts genfs_context_def
+ ;
+genfs_context_def : GENFSCON identifier path '-' identifier security_context_def
+ {if (define_genfs_context(1)) return -1;}
+ | GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
+ {if (define_genfs_context(1)) return -1;}
+ | GENFSCON identifier path security_context_def
+ {if (define_genfs_context(0)) return -1;}
+ ;
+ipv4_addr_def : IPV4_ADDR
+ { if (insert_id(yytext,0)) return -1; }
+ ;
+security_context_def : identifier ':' identifier ':' identifier opt_mls_range_def
+ ;
+opt_mls_range_def : ':' mls_range_def
+ |
+ ;
+mls_range_def : mls_level_def '-' mls_level_def
+ {if (insert_separator(0)) return -1;}
+ | mls_level_def
+ {if (insert_separator(0)) return -1;}
+ ;
+mls_level_def : identifier ':' id_comma_list
+ {if (insert_separator(0)) return -1;}
+ | identifier
+ {if (insert_separator(0)) return -1;}
+ ;
+id_comma_list : identifier
+ | id_comma_list ',' identifier
+ ;
+tilde : '~'
+ ;
+asterisk : '*'
+ ;
+names : identifier
+ { if (insert_separator(0)) return -1; }
+ | nested_id_set
+ { if (insert_separator(0)) return -1; }
+ | asterisk
+ { if (insert_id("*", 0)) return -1;
+ if (insert_separator(0)) return -1; }
+ | tilde identifier
+ { if (insert_id("~", 0)) return -1;
+ if (insert_separator(0)) return -1; }
+ | tilde nested_id_set
+ { if (insert_id("~", 0)) return -1;
+ if (insert_separator(0)) return -1; }
+ | identifier '-' { if (insert_id("-", 0)) return -1; } identifier
+ { if (insert_separator(0)) return -1; }
+ ;
+tilde_push : tilde
+ { if (insert_id("~", 1)) return -1; }
+ ;
+asterisk_push : asterisk
+ { if (insert_id("*", 1)) return -1; }
+ ;
+names_push : identifier_push
+ | '{' identifier_list_push '}'
+ | asterisk_push
+ | tilde_push identifier_push
+ | tilde_push '{' identifier_list_push '}'
+ ;
+identifier_list_push : identifier_push
+ | identifier_list_push identifier_push
+ ;
+identifier_push : IDENTIFIER
+ { if (insert_id(yytext, 1)) return -1; }
+ ;
+identifier_list : identifier
+ | identifier_list identifier
+ ;
+nested_id_set : '{' nested_id_list '}'
+ ;
+nested_id_list : nested_id_element | nested_id_list nested_id_element
+ ;
+nested_id_element : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
+ ;
+identifier : IDENTIFIER
+ { if (insert_id(yytext,0)) return -1; }
+ ;
+path : PATH
+ { if (insert_id(yytext,0)) return -1; }
+ ;
+number : NUMBER
+ { $$ = strtoul(yytext,NULL,0); }
+ ;
+ipv6_addr : IPV6_ADDR
+ { if (insert_id(yytext,0)) return -1; }
+ ;
+policycap_def : POLICYCAP identifier ';'
+ {if (define_polcap()) return -1;}
+ ;
+permissive_def : PERMISSIVE identifier ';'
+ {if (define_permissive()) return -1;}
+
+/*********** module grammar below ***********/
+
+module_policy : module_def avrules_block
+ { if (end_avrule_block(pass) == -1) return -1;
+ if (policydb_index_others(NULL, policydbp, 0)) return -1;
+ }
+ ;
+module_def : MODULE identifier version_identifier ';'
+ { if (define_policy(pass, 1) == -1) return -1; }
+ ;
+version_identifier : VERSION_IDENTIFIER
+ { if (insert_id(yytext,0)) return -1; }
+ | ipv4_addr_def /* version can look like ipv4 address */
+ ;
+avrules_block : avrule_decls avrule_user_defs
+ ;
+avrule_decls : avrule_decls avrule_decl
+ | avrule_decl
+ ;
+avrule_decl : rbac_decl
+ | te_decl
+ | cond_stmt_def
+ | require_block
+ | optional_block
+ | ';'
+ ;
+require_block : REQUIRE '{' require_list '}'
+ ;
+require_list : require_list require_decl
+ | require_decl
+ ;
+require_decl : require_class ';'
+ | require_decl_def require_id_list ';'
+ ;
+require_class : CLASS identifier names
+ { if (require_class(pass)) return -1; }
+ ;
+require_decl_def : ROLE { $$ = require_role; }
+ | TYPE { $$ = require_type; }
+ | ATTRIBUTE { $$ = require_attribute; }
+ | USER { $$ = require_user; }
+ | BOOL { $$ = require_bool; }
+ | SENSITIVITY { $$ = require_sens; }
+ | CATEGORY { $$ = require_cat; }
+ ;
+require_id_list : identifier
+ { if ($<require_func>0 (pass)) return -1; }
+ | require_id_list ',' identifier
+ { if ($<require_func>0 (pass)) return -1; }
+ ;
+optional_block : optional_decl '{' avrules_block '}'
+ { if (end_avrule_block(pass) == -1) return -1; }
+ optional_else
+ { if (end_optional(pass) == -1) return -1; }
+ ;
+optional_else : else_decl '{' avrules_block '}'
+ { if (end_avrule_block(pass) == -1) return -1; }
+ | /* empty */
+ ;
+optional_decl : OPTIONAL
+ { if (begin_optional(pass) == -1) return -1; }
+ ;
+else_decl : ELSE
+ { if (begin_optional_else(pass) == -1) return -1; }
+ ;
+avrule_user_defs : user_def avrule_user_defs
+ | /* empty */
+ ;