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