1 
2 /*
3  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
4  */
5 
6 /*
7  * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
8  *
9  *	Support for enhanced MLS infrastructure.
10  *
11  * Updated: David Caplan, <dac@tresys.com>
12  *
13  * 	Added conditional policy language extensions
14  *
15  * Updated: Joshua Brindle <jbrindle@tresys.com>
16  *	    Karl MacMillan <kmacmillan@mentalrootkit.com>
17  *          Jason Tang     <jtang@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