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