Home | History | Annotate | Download | only in checkpolicy
      1 
      2 /*
      3  * Author : Stephen Smalley, <sds (at) epoch.ncsc.mil>
      4  */
      5 
      6 /*
      7  * Updated: Trusted Computer Solutions, Inc. <dgoeddel (at) trustedcs.com>
      8  *
      9  *	Support for enhanced MLS infrastructure.
     10  *
     11  * Updated: David Caplan, <dac (at) tresys.com>
     12  *
     13  * 	Added conditional policy language extensions
     14  *
     15  * Updated: Joshua Brindle <jbrindle (at) tresys.com>
     16  *	    Karl MacMillan <kmacmillan (at) mentalrootkit.com>
     17  *          Jason Tang     <jtang (at) tresys.com>
     18  *
     19  *	Added support for binary policy modules
     20  *
     21  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
     22  * Copyright (C) 2003 - 2008 Tresys Technology, LLC
     23  * Copyright (C) 2007 Red Hat Inc.
     24  *	This program is free software; you can redistribute it and/or modify
     25  *  	it under the terms of the GNU General Public License as published by
     26  *	the Free Software Foundation, version 2.
     27  */
     28 
     29 /* FLASK */
     30 
     31 %{
     32 #include <sys/types.h>
     33 #include <assert.h>
     34 #include <stdarg.h>
     35 #include <stdint.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <sys/socket.h>
     40 #include <netinet/in.h>
     41 #include <arpa/inet.h>
     42 #include <stdlib.h>
     43 
     44 #include <sepol/policydb/expand.h>
     45 #include <sepol/policydb/policydb.h>
     46 #include <sepol/policydb/services.h>
     47 #include <sepol/policydb/conditional.h>
     48 #include <sepol/policydb/flask.h>
     49 #include <sepol/policydb/hierarchy.h>
     50 #include <sepol/policydb/polcaps.h>
     51 #include "queue.h"
     52 #include "checkpolicy.h"
     53 #include "module_compiler.h"
     54 #include "policy_define.h"
     55 
     56 extern policydb_t *policydbp;
     57 extern unsigned int pass;
     58 
     59 extern char yytext[];
     60 extern int yylex(void);
     61 extern int yywarn(const char *msg);
     62 extern int yyerror(const char *msg);
     63 
     64 typedef int (* require_func_t)(int pass);
     65 
     66 %}
     67 
     68 %union {
     69 	unsigned int val;
     70 	uint64_t val64;
     71 	uintptr_t valptr;
     72 	void *ptr;
     73         require_func_t require_func;
     74 }
     75 
     76 %type <ptr> cond_expr cond_expr_prim cond_pol_list cond_else
     77 %type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def
     78 %type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def
     79 %type <ptr> role_def roles
     80 %type <valptr> cexpr cexpr_prim op role_mls_op
     81 %type <val> ipv4_addr_def number
     82 %type <val64> number64
     83 %type <require_func> require_decl_def
     84 
     85 %token PATH
     86 %token QPATH
     87 %token FILENAME
     88 %token CLONE
     89 %token COMMON
     90 %token CLASS
     91 %token CONSTRAIN
     92 %token VALIDATETRANS
     93 %token INHERITS
     94 %token SID
     95 %token ROLE
     96 %token ROLEATTRIBUTE
     97 %token ATTRIBUTE_ROLE
     98 %token ROLES
     99 %token TYPEALIAS
    100 %token TYPEATTRIBUTE
    101 %token TYPEBOUNDS
    102 %token TYPE
    103 %token TYPES
    104 %token ALIAS
    105 %token ATTRIBUTE
    106 %token BOOL
    107 %token TUNABLE
    108 %token IF
    109 %token ELSE
    110 %token TYPE_TRANSITION
    111 %token TYPE_MEMBER
    112 %token TYPE_CHANGE
    113 %token ROLE_TRANSITION
    114 %token RANGE_TRANSITION
    115 %token SENSITIVITY
    116 %token DOMINANCE
    117 %token DOM DOMBY INCOMP
    118 %token CATEGORY
    119 %token LEVEL
    120 %token RANGE
    121 %token MLSCONSTRAIN
    122 %token MLSVALIDATETRANS
    123 %token USER
    124 %token NEVERALLOW
    125 %token ALLOW
    126 %token AUDITALLOW
    127 %token AUDITDENY
    128 %token DONTAUDIT
    129 %token SOURCE
    130 %token TARGET
    131 %token SAMEUSER
    132 %token FSCON PORTCON NETIFCON NODECON
    133 %token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON
    134 %token FSUSEXATTR FSUSETASK FSUSETRANS
    135 %token GENFSCON
    136 %token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
    137 %token NOT AND OR XOR
    138 %token CTRUE CFALSE
    139 %token IDENTIFIER
    140 %token NUMBER
    141 %token EQUALS
    142 %token NOTEQUAL
    143 %token IPV4_ADDR
    144 %token IPV6_ADDR
    145 %token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
    146 %token POLICYCAP
    147 %token PERMISSIVE
    148 %token FILESYSTEM
    149 %token DEFAULT_USER DEFAULT_ROLE DEFAULT_TYPE DEFAULT_RANGE
    150 %token LOW_HIGH LOW HIGH
    151 
    152 %left OR
    153 %left XOR
    154 %left AND
    155 %right NOT
    156 %left EQUALS NOTEQUAL
    157 %%
    158 policy			: base_policy
    159                         | module_policy
    160                         ;
    161 base_policy             : { if (define_policy(pass, 0) == -1) return -1; }
    162                           classes initial_sids access_vectors
    163                           { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; }
    164                             else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1; }}
    165 			  opt_default_rules opt_mls te_rbac users opt_constraints
    166                          { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
    167 			   else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
    168 			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
    169 			;
    170 classes			: class_def
    171 			| classes class_def
    172 			;
    173 class_def		: CLASS identifier
    174 			{if (define_class()) return -1;}
    175 			;
    176 initial_sids 		: initial_sid_def
    177 			| initial_sids initial_sid_def
    178 			;
    179 initial_sid_def		: SID identifier
    180                         {if (define_initial_sid()) return -1;}
    181 			;
    182 access_vectors		: opt_common_perms av_perms
    183 			;
    184 opt_common_perms        : common_perms
    185                         |
    186                         ;
    187 common_perms		: common_perms_def
    188 			| common_perms common_perms_def
    189 			;
    190 common_perms_def	: COMMON identifier '{' identifier_list '}'
    191 			{if (define_common_perms()) return -1;}
    192 			;
    193 av_perms		: av_perms_def
    194 			| av_perms av_perms_def
    195 			;
    196 av_perms_def		: CLASS identifier '{' identifier_list '}'
    197 			{if (define_av_perms(FALSE)) return -1;}
    198                         | CLASS identifier INHERITS identifier
    199 			{if (define_av_perms(TRUE)) return -1;}
    200                         | CLASS identifier INHERITS identifier '{' identifier_list '}'
    201 			{if (define_av_perms(TRUE)) return -1;}
    202 			;
    203 opt_default_rules	: default_rules
    204 			|
    205 			;
    206 default_rules		: default_user_def
    207 			| default_role_def
    208 			| default_type_def
    209 			| default_range_def
    210 			| default_rules default_user_def
    211 			| default_rules default_role_def
    212 			| default_rules default_type_def
    213 			| default_rules default_range_def
    214 			;
    215 default_user_def	: DEFAULT_USER names SOURCE ';'
    216 			{if (define_default_user(DEFAULT_SOURCE)) return -1; }
    217 			| DEFAULT_USER names TARGET ';'
    218 			{if (define_default_user(DEFAULT_TARGET)) return -1; }
    219 			;
    220 default_role_def	: DEFAULT_ROLE names SOURCE ';'
    221 			{if (define_default_role(DEFAULT_SOURCE)) return -1; }
    222 			| DEFAULT_ROLE names TARGET ';'
    223 			{if (define_default_role(DEFAULT_TARGET)) return -1; }
    224 			;
    225 default_type_def	: DEFAULT_TYPE names SOURCE ';'
    226 			{if (define_default_type(DEFAULT_SOURCE)) return -1; }
    227 			| DEFAULT_TYPE names TARGET ';'
    228 			{if (define_default_type(DEFAULT_TARGET)) return -1; }
    229 			;
    230 default_range_def	: DEFAULT_RANGE names SOURCE LOW ';'
    231 			{if (define_default_range(DEFAULT_SOURCE_LOW)) return -1; }
    232 			| DEFAULT_RANGE names SOURCE HIGH ';'
    233 			{if (define_default_range(DEFAULT_SOURCE_HIGH)) return -1; }
    234 			| DEFAULT_RANGE names SOURCE LOW_HIGH ';'
    235 			{if (define_default_range(DEFAULT_SOURCE_LOW_HIGH)) return -1; }
    236 			| DEFAULT_RANGE names TARGET LOW ';'
    237 			{if (define_default_range(DEFAULT_TARGET_LOW)) return -1; }
    238 			| DEFAULT_RANGE names TARGET HIGH ';'
    239 			{if (define_default_range(DEFAULT_TARGET_HIGH)) return -1; }
    240 			| DEFAULT_RANGE names TARGET LOW_HIGH ';'
    241 			{if (define_default_range(DEFAULT_TARGET_LOW_HIGH)) return -1; }
    242 			;
    243 opt_mls			: mls
    244                         |
    245 			;
    246 mls			: sensitivities dominance opt_categories levels mlspolicy
    247 			;
    248 sensitivities	 	: sensitivity_def
    249 			| sensitivities sensitivity_def
    250 			;
    251 sensitivity_def		: SENSITIVITY identifier alias_def ';'
    252 			{if (define_sens()) return -1;}
    253 			| SENSITIVITY identifier ';'
    254 			{if (define_sens()) return -1;}
    255 	                ;
    256 alias_def		: ALIAS names
    257 			;
    258 dominance		: DOMINANCE identifier
    259 			{if (define_dominance()) return -1;}
    260                         | DOMINANCE '{' identifier_list '}'
    261 			{if (define_dominance()) return -1;}
    262 			;
    263 opt_categories          : categories
    264                         |
    265                         ;
    266 categories 		: category_def
    267 			| categories category_def
    268 			;
    269 category_def		: CATEGORY identifier alias_def ';'
    270 			{if (define_category()) return -1;}
    271 			| CATEGORY identifier ';'
    272 			{if (define_category()) return -1;}
    273 			;
    274 levels	 		: level_def
    275 			| levels level_def
    276 			;
    277 level_def		: LEVEL identifier ':' id_comma_list ';'
    278 			{if (define_level()) return -1;}
    279 			| LEVEL identifier ';'
    280 			{if (define_level()) return -1;}
    281 			;
    282 mlspolicy		: mlspolicy_decl
    283 			| mlspolicy mlspolicy_decl
    284 			;
    285 mlspolicy_decl		: mlsconstraint_def
    286 			| mlsvalidatetrans_def
    287 			;
    288 mlsconstraint_def	: MLSCONSTRAIN names names cexpr ';'
    289 			{ if (define_constraint((constraint_expr_t*)$4)) return -1; }
    290 			;
    291 mlsvalidatetrans_def	: MLSVALIDATETRANS names cexpr ';'
    292 			{ if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
    293 			;
    294 te_rbac			: te_rbac_decl
    295 			| te_rbac te_rbac_decl
    296 			;
    297 te_rbac_decl		: te_decl
    298 			| rbac_decl
    299                         | cond_stmt_def
    300 			| optional_block
    301 			| policycap_def
    302 			| ';'
    303                         ;
    304 rbac_decl		: attribute_role_def
    305 			| role_type_def
    306                         | role_dominance
    307                         | role_trans_def
    308  			| role_allow_def
    309 			| roleattribute_def
    310 			| role_attr_def
    311 			;
    312 te_decl			: attribute_def
    313                         | type_def
    314                         | typealias_def
    315                         | typeattribute_def
    316                         | typebounds_def
    317                         | bool_def
    318 			| tunable_def
    319                         | transition_def
    320                         | range_trans_def
    321                         | te_avtab_def
    322 			| permissive_def
    323 			;
    324 attribute_def           : ATTRIBUTE identifier ';'
    325                         { if (define_attrib()) return -1;}
    326                         ;
    327 type_def		: TYPE identifier alias_def opt_attr_list ';'
    328                         {if (define_type(1)) return -1;}
    329 	                | TYPE identifier opt_attr_list ';'
    330                         {if (define_type(0)) return -1;}
    331     			;
    332 typealias_def           : TYPEALIAS identifier alias_def ';'
    333 			{if (define_typealias()) return -1;}
    334 			;
    335 typeattribute_def	: TYPEATTRIBUTE identifier id_comma_list ';'
    336 			{if (define_typeattribute()) return -1;}
    337 			;
    338 typebounds_def          : TYPEBOUNDS identifier id_comma_list ';'
    339                         {if (define_typebounds()) return -1;}
    340                         ;
    341 opt_attr_list           : ',' id_comma_list
    342 			|
    343 			;
    344 bool_def                : BOOL identifier bool_val ';'
    345                         { if (define_bool_tunable(0)) return -1; }
    346                         ;
    347 tunable_def		: TUNABLE identifier bool_val ';'
    348 			{ if (define_bool_tunable(1)) return -1; }
    349 			;
    350 bool_val                : CTRUE
    351  			{ if (insert_id("T",0)) return -1; }
    352                         | CFALSE
    353 			{ if (insert_id("F",0)) return -1; }
    354                         ;
    355 cond_stmt_def           : IF cond_expr '{' cond_pol_list '}' cond_else
    356                         { if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (avrule_t*)$4, (avrule_t*)$6) < 0) return -1;  }}
    357                         ;
    358 cond_else		: ELSE '{' cond_pol_list '}'
    359 			{ $$ = $3; }
    360 			| /* empty */
    361 			{ $$ = NULL; }
    362 			;
    363 cond_expr               : '(' cond_expr ')'
    364 			{ $$ = $2;}
    365 			| NOT cond_expr
    366 			{ $$ = define_cond_expr(COND_NOT, $2, 0);
    367 			  if ($$ == 0) return -1; }
    368 			| cond_expr AND cond_expr
    369 			{ $$ = define_cond_expr(COND_AND, $1, $3);
    370 			  if ($$ == 0) return  -1; }
    371 			| cond_expr OR cond_expr
    372 			{ $$ = define_cond_expr(COND_OR, $1, $3);
    373 			  if ($$ == 0) return   -1; }
    374 			| cond_expr XOR cond_expr
    375 			{ $$ = define_cond_expr(COND_XOR, $1, $3);
    376 			  if ($$ == 0) return  -1; }
    377 			| cond_expr EQUALS cond_expr
    378 			{ $$ = define_cond_expr(COND_EQ, $1, $3);
    379 			  if ($$ == 0) return  -1; }
    380 			| cond_expr NOTEQUAL cond_expr
    381 			{ $$ = define_cond_expr(COND_NEQ, $1, $3);
    382 			  if ($$ == 0) return  -1; }
    383 			| cond_expr_prim
    384 			{ $$ = $1; }
    385 			;
    386 cond_expr_prim          : identifier
    387                         { $$ = define_cond_expr(COND_BOOL,0, 0);
    388 			  if ($$ == COND_ERR) return   -1; }
    389                         ;
    390 cond_pol_list           : cond_pol_list cond_rule_def
    391                         { $$ = define_cond_pol_list((avrule_t *)$1, (avrule_t *)$2); }
    392 			| /* empty */
    393 			{ $$ = NULL; }
    394 			;
    395 cond_rule_def           : cond_transition_def
    396                         { $$ = $1; }
    397                         | cond_te_avtab_def
    398                         { $$ = $1; }
    399 			| require_block
    400 			{ $$ = NULL; }
    401                         ;
    402 cond_transition_def	: TYPE_TRANSITION names names ':' names identifier filename ';'
    403                         { $$ = define_cond_filename_trans() ;
    404                           if ($$ == COND_ERR) return -1;}
    405 			| TYPE_TRANSITION names names ':' names identifier ';'
    406                         { $$ = define_cond_compute_type(AVRULE_TRANSITION) ;
    407                           if ($$ == COND_ERR) return -1;}
    408                         | TYPE_MEMBER names names ':' names identifier ';'
    409                         { $$ = define_cond_compute_type(AVRULE_MEMBER) ;
    410                           if ($$ ==  COND_ERR) return -1;}
    411                         | TYPE_CHANGE names names ':' names identifier ';'
    412                         { $$ = define_cond_compute_type(AVRULE_CHANGE) ;
    413                           if ($$ == COND_ERR) return -1;}
    414     			;
    415 cond_te_avtab_def	: cond_allow_def
    416                           { $$ = $1; }
    417 			| cond_auditallow_def
    418 			  { $$ = $1; }
    419 			| cond_auditdeny_def
    420 			  { $$ = $1; }
    421 			| cond_dontaudit_def
    422 			  { $$ = $1; }
    423 			;
    424 cond_allow_def		: ALLOW names names ':' names names  ';'
    425 			{ $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
    426                           if ($$ == COND_ERR) return -1; }
    427 		        ;
    428 cond_auditallow_def	: AUDITALLOW names names ':' names names ';'
    429 			{ $$ = define_cond_te_avtab(AVRULE_AUDITALLOW) ;
    430                           if ($$ == COND_ERR) return -1; }
    431 		        ;
    432 cond_auditdeny_def	: AUDITDENY names names ':' names names ';'
    433 			{ $$ = define_cond_te_avtab(AVRULE_AUDITDENY) ;
    434                           if ($$ == COND_ERR) return -1; }
    435 		        ;
    436 cond_dontaudit_def	: DONTAUDIT names names ':' names names ';'
    437 			{ $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
    438                           if ($$ == COND_ERR) return -1; }
    439 		        ;
    440 			;
    441 transition_def		: TYPE_TRANSITION  names names ':' names identifier filename ';'
    442 			{if (define_filename_trans()) return -1; }
    443 			| TYPE_TRANSITION names names ':' names identifier ';'
    444                         {if (define_compute_type(AVRULE_TRANSITION)) return -1;}
    445                         | TYPE_MEMBER names names ':' names identifier ';'
    446                         {if (define_compute_type(AVRULE_MEMBER)) return -1;}
    447                         | TYPE_CHANGE names names ':' names identifier ';'
    448                         {if (define_compute_type(AVRULE_CHANGE)) return -1;}
    449     			;
    450 range_trans_def		: RANGE_TRANSITION names names mls_range_def ';'
    451 			{ if (define_range_trans(0)) return -1; }
    452 			| RANGE_TRANSITION names names ':' names mls_range_def ';'
    453 			{ if (define_range_trans(1)) return -1; }
    454 			;
    455 te_avtab_def		: allow_def
    456 			| auditallow_def
    457 			| auditdeny_def
    458 			| dontaudit_def
    459 			| neverallow_def
    460 			| operation_allow_def
    461 			| operation_auditallow_def
    462 			| operation_dontaudit_def
    463 			;
    464 allow_def		: ALLOW names names ':' names names  ';'
    465 			{if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
    466 		        ;
    467 auditallow_def		: AUDITALLOW names names ':' names names ';'
    468 			{if (define_te_avtab(AVRULE_AUDITALLOW)) return -1; }
    469 		        ;
    470 auditdeny_def		: AUDITDENY names names ':' names names ';'
    471 			{if (define_te_avtab(AVRULE_AUDITDENY)) return -1; }
    472 		        ;
    473 dontaudit_def		: DONTAUDIT names names ':' names names ';'
    474 			{if (define_te_avtab(AVRULE_DONTAUDIT)) return -1; }
    475 		        ;
    476 neverallow_def		: NEVERALLOW names names ':' names names  ';'
    477 			{if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
    478 		        ;
    479 operation_allow_def	: ALLOW names names ':' names  operations ';'
    480 			{if (define_te_avtab_operation(AVRULE_OPNUM_ALLOWED)) return -1; }
    481 		        ;
    482 operation_auditallow_def: AUDITALLOW names names ':' names operations ';'
    483 			{if (define_te_avtab_operation(AVRULE_OPNUM_AUDITALLOW)) return -1; }
    484 		        ;
    485 operation_dontaudit_def	: DONTAUDIT names names ':' names operations ';'
    486 			{if (define_te_avtab_operation(AVRULE_OPNUM_DONTAUDIT)) return -1; }
    487 		        ;
    488 attribute_role_def	: ATTRIBUTE_ROLE identifier ';'
    489 			{if (define_attrib_role()) return -1; }
    490 		        ;
    491 role_type_def		: ROLE identifier TYPES names ';'
    492 			{if (define_role_types()) return -1;}
    493 			;
    494 role_attr_def		: ROLE identifier opt_attr_list ';'
    495  			{if (define_role_attr()) return -1;}
    496                         ;
    497 role_dominance		: DOMINANCE '{' roles '}'
    498 			;
    499 role_trans_def		: ROLE_TRANSITION names names identifier ';'
    500 			{if (define_role_trans(0)) return -1; }
    501 			| ROLE_TRANSITION names names ':' names identifier ';'
    502 			{if (define_role_trans(1)) return -1;}
    503 			;
    504 role_allow_def		: ALLOW names names ';'
    505 			{if (define_role_allow()) return -1; }
    506 			;
    507 roles			: role_def
    508 			{ $$ = $1; }
    509 			| roles role_def
    510 			{ $$ = merge_roles_dom((role_datum_t*)$1, (role_datum_t*)$2); if ($$ == 0) return -1;}
    511 			;
    512 role_def		: ROLE identifier_push ';'
    513                         {$$ = define_role_dom(NULL); if ($$ == 0) return -1;}
    514 			| ROLE identifier_push '{' roles '}'
    515                         {$$ = define_role_dom((role_datum_t*)$4); if ($$ == 0) return -1;}
    516 			;
    517 roleattribute_def	: ROLEATTRIBUTE identifier id_comma_list ';'
    518 			{if (define_roleattribute()) return -1;}
    519 			;
    520 opt_constraints         : constraints
    521                         |
    522                         ;
    523 constraints		: constraint_decl
    524 			| constraints constraint_decl
    525 			;
    526 constraint_decl		: constraint_def
    527 			| validatetrans_def
    528 			;
    529 constraint_def		: CONSTRAIN names names cexpr ';'
    530 			{ if (define_constraint((constraint_expr_t*)$4)) return -1; }
    531 			;
    532 validatetrans_def	: VALIDATETRANS names cexpr ';'
    533 			{ if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
    534 			;
    535 cexpr			: '(' cexpr ')'
    536 			{ $$ = $2; }
    537 			| NOT cexpr
    538 			{ $$ = define_cexpr(CEXPR_NOT, $2, 0);
    539 			  if ($$ == 0) return -1; }
    540 			| cexpr AND cexpr
    541 			{ $$ = define_cexpr(CEXPR_AND, $1, $3);
    542 			  if ($$ == 0) return -1; }
    543 			| cexpr OR cexpr
    544 			{ $$ = define_cexpr(CEXPR_OR, $1, $3);
    545 			  if ($$ == 0) return -1; }
    546 			| cexpr_prim
    547 			{ $$ = $1; }
    548 			;
    549 cexpr_prim		: U1 op U2
    550 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, $2);
    551 			  if ($$ == 0) return -1; }
    552 			| R1 role_mls_op R2
    553 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
    554 			  if ($$ == 0) return -1; }
    555 			| T1 op T2
    556 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_TYPE, $2);
    557 			  if ($$ == 0) return -1; }
    558 			| U1 op { if (insert_separator(1)) return -1; } names_push
    559 			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_USER, $2);
    560 			  if ($$ == 0) return -1; }
    561 			| U2 op { if (insert_separator(1)) return -1; } names_push
    562 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_TARGET), $2);
    563 			  if ($$ == 0) return -1; }
    564 			| U3 op { if (insert_separator(1)) return -1; } names_push
    565 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_XTARGET), $2);
    566 			  if ($$ == 0) return -1; }
    567 			| R1 op { if (insert_separator(1)) return -1; } names_push
    568 			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, $2);
    569 			  if ($$ == 0) return -1; }
    570 			| R2 op { if (insert_separator(1)) return -1; } names_push
    571 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), $2);
    572 			  if ($$ == 0) return -1; }
    573 			| R3 op { if (insert_separator(1)) return -1; } names_push
    574 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
    575 			  if ($$ == 0) return -1; }
    576 			| T1 op { if (insert_separator(1)) return -1; } names_push
    577 			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
    578 			  if ($$ == 0) return -1; }
    579 			| T2 op { if (insert_separator(1)) return -1; } names_push
    580 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
    581 			  if ($$ == 0) return -1; }
    582 			| T3 op { if (insert_separator(1)) return -1; } names_push
    583 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
    584 			  if ($$ == 0) return -1; }
    585 			| SAMEUSER
    586 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, CEXPR_EQ);
    587 			  if ($$ == 0) return -1; }
    588 			| SOURCE ROLE { if (insert_separator(1)) return -1; } names_push
    589 			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, CEXPR_EQ);
    590 			  if ($$ == 0) return -1; }
    591 			| TARGET ROLE { if (insert_separator(1)) return -1; } names_push
    592 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), CEXPR_EQ);
    593 			  if ($$ == 0) return -1; }
    594 			| ROLE role_mls_op
    595 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
    596 			  if ($$ == 0) return -1; }
    597 			| SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
    598 			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
    599 			  if ($$ == 0) return -1; }
    600 			| TARGET TYPE { if (insert_separator(1)) return -1; } names_push
    601 			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
    602 			  if ($$ == 0) return -1; }
    603 			| L1 role_mls_op L2
    604 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1L2, $2);
    605 			  if ($$ == 0) return -1; }
    606 			| L1 role_mls_op H2
    607 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H2, $2);
    608 			  if ($$ == 0) return -1; }
    609 			| H1 role_mls_op L2
    610 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1L2, $2);
    611 			  if ($$ == 0) return -1; }
    612 			| H1 role_mls_op H2
    613 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1H2, $2);
    614 			  if ($$ == 0) return -1; }
    615 			| L1 role_mls_op H1
    616 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H1, $2);
    617 			  if ($$ == 0) return -1; }
    618 			| L2 role_mls_op H2
    619 			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L2H2, $2);
    620 			  if ($$ == 0) return -1; }
    621 			;
    622 op			: EQUALS
    623 			{ $$ = CEXPR_EQ; }
    624 			| NOTEQUAL
    625 			{ $$ = CEXPR_NEQ; }
    626 			;
    627 role_mls_op		: op
    628 			{ $$ = $1; }
    629 			| DOM
    630 			{ $$ = CEXPR_DOM; }
    631 			| DOMBY
    632 			{ $$ = CEXPR_DOMBY; }
    633 			| INCOMP
    634 			{ $$ = CEXPR_INCOMP; }
    635 			;
    636 users			: user_def
    637 			| users user_def
    638 			;
    639 user_def		: USER identifier ROLES names opt_mls_user ';'
    640 	                {if (define_user()) return -1;}
    641 			;
    642 opt_mls_user		: LEVEL mls_level_def RANGE mls_range_def
    643 			|
    644 			;
    645 initial_sid_contexts	: initial_sid_context_def
    646 			| initial_sid_contexts initial_sid_context_def
    647 			;
    648 initial_sid_context_def	: SID identifier security_context_def
    649 			{if (define_initial_sid_context()) return -1;}
    650 			;
    651 opt_dev_contexts	: dev_contexts |
    652 			;
    653 dev_contexts		: dev_context_def
    654 			| dev_contexts dev_context_def
    655 			;
    656 dev_context_def		: pirq_context_def |
    657 			  iomem_context_def |
    658 			  ioport_context_def |
    659 			  pci_context_def |
    660 			  dtree_context_def
    661 			;
    662 pirq_context_def 	: PIRQCON number security_context_def
    663 		        {if (define_pirq_context($2)) return -1;}
    664 		        ;
    665 iomem_context_def	: IOMEMCON number64 security_context_def
    666 		        {if (define_iomem_context($2,$2)) return -1;}
    667 		        | IOMEMCON number64 '-' number64 security_context_def
    668 		        {if (define_iomem_context($2,$4)) return -1;}
    669 		        ;
    670 ioport_context_def	: IOPORTCON number security_context_def
    671 			{if (define_ioport_context($2,$2)) return -1;}
    672 			| IOPORTCON number '-' number security_context_def
    673 			{if (define_ioport_context($2,$4)) return -1;}
    674 			;
    675 pci_context_def  	: PCIDEVICECON number security_context_def
    676 		        {if (define_pcidevice_context($2)) return -1;}
    677 		        ;
    678 dtree_context_def	: DEVICETREECON path security_context_def
    679 		        {if (define_devicetree_context()) return -1;}
    680 		        ;
    681 opt_fs_contexts         : fs_contexts
    682                         |
    683                         ;
    684 fs_contexts		: fs_context_def
    685 			| fs_contexts fs_context_def
    686 			;
    687 fs_context_def		: FSCON number number security_context_def security_context_def
    688 			{if (define_fs_context($2,$3)) return -1;}
    689 			;
    690 net_contexts		: opt_port_contexts opt_netif_contexts opt_node_contexts
    691 			;
    692 opt_port_contexts       : port_contexts
    693                         |
    694                         ;
    695 port_contexts		: port_context_def
    696 			| port_contexts port_context_def
    697 			;
    698 port_context_def	: PORTCON identifier number security_context_def
    699 			{if (define_port_context($3,$3)) return -1;}
    700 			| PORTCON identifier number '-' number security_context_def
    701 			{if (define_port_context($3,$5)) return -1;}
    702 			;
    703 opt_netif_contexts      : netif_contexts
    704                         |
    705                         ;
    706 netif_contexts		: netif_context_def
    707 			| netif_contexts netif_context_def
    708 			;
    709 netif_context_def	: NETIFCON identifier security_context_def security_context_def
    710 			{if (define_netif_context()) return -1;}
    711 			;
    712 opt_node_contexts       : node_contexts
    713                         |
    714                         ;
    715 node_contexts		: node_context_def
    716 			| node_contexts node_context_def
    717 			;
    718 node_context_def	: NODECON ipv4_addr_def ipv4_addr_def security_context_def
    719 			{if (define_ipv4_node_context()) return -1;}
    720 			| NODECON ipv6_addr ipv6_addr security_context_def
    721 			{if (define_ipv6_node_context()) return -1;}
    722 			;
    723 opt_fs_uses             : fs_uses
    724                         |
    725                         ;
    726 fs_uses                 : fs_use_def
    727                         | fs_uses fs_use_def
    728                         ;
    729 fs_use_def              : FSUSEXATTR filesystem security_context_def ';'
    730                         {if (define_fs_use(SECURITY_FS_USE_XATTR)) return -1;}
    731                         | FSUSETASK identifier security_context_def ';'
    732                         {if (define_fs_use(SECURITY_FS_USE_TASK)) return -1;}
    733                         | FSUSETRANS identifier security_context_def ';'
    734                         {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
    735                         ;
    736 opt_genfs_contexts      : genfs_contexts
    737                         |
    738                         ;
    739 genfs_contexts          : genfs_context_def
    740                         | genfs_contexts genfs_context_def
    741                         ;
    742 genfs_context_def	: GENFSCON filesystem path '-' identifier security_context_def
    743 			{if (define_genfs_context(1)) return -1;}
    744 			| GENFSCON filesystem path '-' '-' {insert_id("-", 0);} security_context_def
    745 			{if (define_genfs_context(1)) return -1;}
    746                         | GENFSCON filesystem path security_context_def
    747 			{if (define_genfs_context(0)) return -1;}
    748 			;
    749 ipv4_addr_def		: IPV4_ADDR
    750 			{ if (insert_id(yytext,0)) return -1; }
    751 			;
    752 operations		: operation
    753 			{ if (insert_separator(0)) return -1; }
    754 			| nested_operation_set
    755 			{ if (insert_separator(0)) return -1; }
    756 			| tilde operation
    757                         { if (insert_id("~", 0)) return -1; }
    758 			| tilde nested_operation_set
    759 			{ if (insert_id("~", 0)) return -1;
    760 			  if (insert_separator(0)) return -1; }
    761 			;
    762 nested_operation_set	: '{' nested_operation_list '}'
    763 			;
    764 nested_operation_list	: nested_operation_element
    765 			| nested_operation_list nested_operation_element
    766 			;
    767 nested_operation_element: operation '-' { if (insert_id("-", 0)) return -1; } operation
    768 			| operation
    769 			| nested_operation_set
    770 			;
    771 operation		: number
    772                         { if (insert_id(yytext,0)) return -1; }
    773 			;
    774 security_context_def	: identifier ':' identifier ':' identifier opt_mls_range_def
    775 	                ;
    776 opt_mls_range_def	: ':' mls_range_def
    777 			|
    778 			;
    779 mls_range_def		: mls_level_def '-' mls_level_def
    780 			{if (insert_separator(0)) return -1;}
    781 	                | mls_level_def
    782 			{if (insert_separator(0)) return -1;}
    783 	                ;
    784 mls_level_def		: identifier ':' id_comma_list
    785 			{if (insert_separator(0)) return -1;}
    786 	                | identifier
    787 			{if (insert_separator(0)) return -1;}
    788 	                ;
    789 id_comma_list           : identifier
    790 			| id_comma_list ',' identifier
    791 			;
    792 tilde			: '~'
    793 			;
    794 asterisk		: '*'
    795 			;
    796 names           	: identifier
    797 			{ if (insert_separator(0)) return -1; }
    798 			| nested_id_set
    799 			{ if (insert_separator(0)) return -1; }
    800 			| asterisk
    801                         { if (insert_id("*", 0)) return -1;
    802 			  if (insert_separator(0)) return -1; }
    803 			| tilde identifier
    804                         { if (insert_id("~", 0)) return -1;
    805 			  if (insert_separator(0)) return -1; }
    806 			| tilde nested_id_set
    807 	 		{ if (insert_id("~", 0)) return -1;
    808 			  if (insert_separator(0)) return -1; }
    809                         | identifier '-' { if (insert_id("-", 0)) return -1; } identifier
    810 			{ if (insert_separator(0)) return -1; }
    811 			;
    812 tilde_push              : tilde
    813                         { if (insert_id("~", 1)) return -1; }
    814 			;
    815 asterisk_push           : asterisk
    816                         { if (insert_id("*", 1)) return -1; }
    817 			;
    818 names_push		: identifier_push
    819 			| '{' identifier_list_push '}'
    820 			| asterisk_push
    821 			| tilde_push identifier_push
    822 			| tilde_push '{' identifier_list_push '}'
    823 			;
    824 identifier_list_push	: identifier_push
    825 			| identifier_list_push identifier_push
    826 			;
    827 identifier_push		: IDENTIFIER
    828 			{ if (insert_id(yytext, 1)) return -1; }
    829 			;
    830 identifier_list		: identifier
    831 			| identifier_list identifier
    832 			;
    833 nested_id_set           : '{' nested_id_list '}'
    834                         ;
    835 nested_id_list          : nested_id_element | nested_id_list nested_id_element
    836                         ;
    837 nested_id_element       : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
    838                         ;
    839 identifier		: IDENTIFIER
    840 			{ if (insert_id(yytext,0)) return -1; }
    841 			;
    842 filesystem		: FILESYSTEM
    843                         { if (insert_id(yytext,0)) return -1; }
    844                         | IDENTIFIER
    845 			{ if (insert_id(yytext,0)) return -1; }
    846                         ;
    847 path     		: PATH
    848 			{ if (insert_id(yytext,0)) return -1; }
    849 			| QPATH
    850 			{ yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
    851 			;
    852 filename		: FILENAME
    853 			{ yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
    854 			;
    855 number			: NUMBER
    856 			{ $$ = strtoul(yytext,NULL,0); }
    857 			;
    858 number64		: NUMBER
    859 			{ $$ = strtoull(yytext,NULL,0); }
    860 			;
    861 ipv6_addr		: IPV6_ADDR
    862 			{ if (insert_id(yytext,0)) return -1; }
    863 			;
    864 policycap_def		: POLICYCAP identifier ';'
    865 			{if (define_polcap()) return -1;}
    866 			;
    867 permissive_def		: PERMISSIVE identifier ';'
    868 			{if (define_permissive()) return -1;}
    869 
    870 /*********** module grammar below ***********/
    871 
    872 module_policy           : module_def avrules_block
    873                         { if (end_avrule_block(pass) == -1) return -1;
    874                           if (policydb_index_others(NULL, policydbp, 0)) return -1;
    875                         }
    876                         ;
    877 module_def              : MODULE identifier version_identifier ';'
    878                         { if (define_policy(pass, 1) == -1) return -1; }
    879                         ;
    880 version_identifier      : VERSION_IDENTIFIER
    881                         { if (insert_id(yytext,0)) return -1; }
    882 			| number
    883                         { if (insert_id(yytext,0)) return -1; }
    884                         | ipv4_addr_def /* version can look like ipv4 address */
    885                         ;
    886 avrules_block           : avrule_decls avrule_user_defs
    887                         ;
    888 avrule_decls            : avrule_decls avrule_decl
    889                         | avrule_decl
    890                         ;
    891 avrule_decl             : rbac_decl
    892                         | te_decl
    893                         | cond_stmt_def
    894                         | require_block
    895                         | optional_block
    896                         | ';'
    897                         ;
    898 require_block           : REQUIRE '{' require_list '}'
    899                         ;
    900 require_list            : require_list require_decl
    901                         | require_decl
    902                         ;
    903 require_decl            : require_class ';'
    904                         | require_decl_def require_id_list ';'
    905                         ;
    906 require_class           : CLASS identifier names
    907                         { if (require_class(pass)) return -1; }
    908                         ;
    909 require_decl_def        : ROLE        { $$ = require_role; }
    910                         | TYPE        { $$ = require_type; }
    911                         | ATTRIBUTE   { $$ = require_attribute; }
    912                         | ATTRIBUTE_ROLE   { $$ = require_attribute_role; }
    913                         | USER        { $$ = require_user; }
    914                         | BOOL        { $$ = require_bool; }
    915 			| TUNABLE     { $$ = require_tunable; }
    916                         | SENSITIVITY { $$ = require_sens; }
    917                         | CATEGORY    { $$ = require_cat; }
    918                         ;
    919 require_id_list         : identifier
    920                         { if ($<require_func>0 (pass)) return -1; }
    921                         | require_id_list ',' identifier
    922                         { if ($<require_func>0 (pass)) return -1; }
    923                         ;
    924 optional_block          : optional_decl '{' avrules_block '}'
    925                         { if (end_avrule_block(pass) == -1) return -1; }
    926                           optional_else
    927                         { if (end_optional(pass) == -1) return -1; }
    928                         ;
    929 optional_else           : else_decl '{' avrules_block '}'
    930                         { if (end_avrule_block(pass) == -1) return -1; }
    931                         | /* empty */
    932                         ;
    933 optional_decl           : OPTIONAL
    934                         { if (begin_optional(pass) == -1) return -1; }
    935                         ;
    936 else_decl               : ELSE
    937                         { if (begin_optional_else(pass) == -1) return -1; }
    938                         ;
    939 avrule_user_defs        : user_def avrule_user_defs
    940                         | /* empty */
    941                         ;
    942