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