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
56extern policydb_t *policydbp;
57extern unsigned int pass;
58
59extern char yytext[];
60extern int yylex(void);
61extern int yywarn(char *msg);
62extern int yyerror(char *msg);
63
64typedef 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%%
153policy			: base_policy
154                        | module_policy
155                        ;
156base_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			;
165classes			: class_def
166			| classes class_def
167			;
168class_def		: CLASS identifier
169			{if (define_class()) return -1;}
170			;
171initial_sids 		: initial_sid_def
172			| initial_sids initial_sid_def
173			;
174initial_sid_def		: SID identifier
175                        {if (define_initial_sid()) return -1;}
176			;
177access_vectors		: opt_common_perms av_perms
178			;
179opt_common_perms        : common_perms
180                        |
181                        ;
182common_perms		: common_perms_def
183			| common_perms common_perms_def
184			;
185common_perms_def	: COMMON identifier '{' identifier_list '}'
186			{if (define_common_perms()) return -1;}
187			;
188av_perms		: av_perms_def
189			| av_perms av_perms_def
190			;
191av_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			;
198opt_mls			: mls
199                        |
200			;
201mls			: sensitivities dominance opt_categories levels mlspolicy
202			;
203sensitivities	 	: sensitivity_def
204			| sensitivities sensitivity_def
205			;
206sensitivity_def		: SENSITIVITY identifier alias_def ';'
207			{if (define_sens()) return -1;}
208			| SENSITIVITY identifier ';'
209			{if (define_sens()) return -1;}
210	                ;
211alias_def		: ALIAS names
212			;
213dominance		: DOMINANCE identifier
214			{if (define_dominance()) return -1;}
215                        | DOMINANCE '{' identifier_list '}'
216			{if (define_dominance()) return -1;}
217			;
218opt_categories          : categories
219                        |
220                        ;
221categories 		: category_def
222			| categories category_def
223			;
224category_def		: CATEGORY identifier alias_def ';'
225			{if (define_category()) return -1;}
226			| CATEGORY identifier ';'
227			{if (define_category()) return -1;}
228			;
229levels	 		: level_def
230			| levels level_def
231			;
232level_def		: LEVEL identifier ':' id_comma_list ';'
233			{if (define_level()) return -1;}
234			| LEVEL identifier ';'
235			{if (define_level()) return -1;}
236			;
237mlspolicy		: mlspolicy_decl
238			| mlspolicy mlspolicy_decl
239			;
240mlspolicy_decl		: mlsconstraint_def
241			| mlsvalidatetrans_def
242			;
243mlsconstraint_def	: MLSCONSTRAIN names names cexpr ';'
244			{ if (define_constraint((constraint_expr_t*)$4)) return -1; }
245			;
246mlsvalidatetrans_def	: MLSVALIDATETRANS names cexpr ';'
247			{ if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
248			;
249te_rbac			: te_rbac_decl
250			| te_rbac te_rbac_decl
251			;
252te_rbac_decl		: te_decl
253			| rbac_decl
254                        | cond_stmt_def
255			| optional_block
256			| policycap_def
257			| ';'
258                        ;
259rbac_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			;
267te_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			;
279attribute_def           : ATTRIBUTE identifier ';'
280                        { if (define_attrib()) return -1;}
281                        ;
282type_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    			;
287typealias_def           : TYPEALIAS identifier alias_def ';'
288			{if (define_typealias()) return -1;}
289			;
290typeattribute_def	: TYPEATTRIBUTE identifier id_comma_list ';'
291			{if (define_typeattribute()) return -1;}
292			;
293typebounds_def          : TYPEBOUNDS identifier id_comma_list ';'
294                        {if (define_typebounds()) return -1;}
295                        ;
296opt_attr_list           : ',' id_comma_list
297			|
298			;
299bool_def                : BOOL identifier bool_val ';'
300                        { if (define_bool_tunable(0)) return -1; }
301                        ;
302tunable_def		: TUNABLE identifier bool_val ';'
303			{ if (define_bool_tunable(1)) return -1; }
304			;
305bool_val                : CTRUE
306 			{ if (insert_id("T",0)) return -1; }
307                        | CFALSE
308			{ if (insert_id("F",0)) return -1; }
309                        ;
310cond_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                        ;
313cond_else		: ELSE '{' cond_pol_list '}'
314			{ $$ = $3; }
315			| /* empty */
316			{ $$ = NULL; }
317cond_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			;
340cond_expr_prim          : identifier
341                        { $$ = define_cond_expr(COND_BOOL,0, 0);
342			  if ($$ == COND_ERR) return   -1; }
343                        ;
344cond_pol_list           : cond_pol_list cond_rule_def
345                        { $$ = define_cond_pol_list((avrule_t *)$1, (avrule_t *)$2); }
346			| /* empty */
347			{ $$ = NULL; }
348			;
349cond_rule_def           : cond_transition_def
350                        { $$ = $1; }
351                        | cond_te_avtab_def
352                        { $$ = $1; }
353			| require_block
354			{ $$ = NULL; }
355                        ;
356cond_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    			;
369cond_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			;
378cond_allow_def		: ALLOW names names ':' names names  ';'
379			{ $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
380                          if ($$ == COND_ERR) return -1; }
381		        ;
382cond_auditallow_def	: AUDITALLOW names names ':' names names ';'
383			{ $$ = define_cond_te_avtab(AVRULE_AUDITALLOW) ;
384                          if ($$ == COND_ERR) return -1; }
385		        ;
386cond_auditdeny_def	: AUDITDENY names names ':' names names ';'
387			{ $$ = define_cond_te_avtab(AVRULE_AUDITDENY) ;
388                          if ($$ == COND_ERR) return -1; }
389		        ;
390cond_dontaudit_def	: DONTAUDIT names names ':' names names ';'
391			{ $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
392                          if ($$ == COND_ERR) return -1; }
393		        ;
394			;
395transition_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    			;
404range_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			;
409te_avtab_def		: allow_def
410			| auditallow_def
411			| auditdeny_def
412			| dontaudit_def
413			| neverallow_def
414			;
415allow_def		: ALLOW names names ':' names names  ';'
416			{if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
417		        ;
418auditallow_def		: AUDITALLOW names names ':' names names ';'
419			{if (define_te_avtab(AVRULE_AUDITALLOW)) return -1; }
420		        ;
421auditdeny_def		: AUDITDENY names names ':' names names ';'
422			{if (define_te_avtab(AVRULE_AUDITDENY)) return -1; }
423		        ;
424dontaudit_def		: DONTAUDIT names names ':' names names ';'
425			{if (define_te_avtab(AVRULE_DONTAUDIT)) return -1; }
426		        ;
427neverallow_def		: NEVERALLOW names names ':' names names  ';'
428			{if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
429		        ;
430attribute_role_def	: ATTRIBUTE_ROLE identifier ';'
431			{if (define_attrib_role()) return -1; }
432		        ;
433role_type_def		: ROLE identifier TYPES names ';'
434			{if (define_role_types()) return -1;}
435			;
436role_attr_def		: ROLE identifier opt_attr_list ';'
437 			{if (define_role_attr()) return -1;}
438                        ;
439role_dominance		: DOMINANCE '{' roles '}'
440			;
441role_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			;
446role_allow_def		: ALLOW names names ';'
447			{if (define_role_allow()) return -1; }
448			;
449roles			: 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			;
454role_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			;
459roleattribute_def	: ROLEATTRIBUTE identifier id_comma_list ';'
460			{if (define_roleattribute()) return -1;}
461			;
462opt_constraints         : constraints
463                        |
464                        ;
465constraints		: constraint_decl
466			| constraints constraint_decl
467			;
468constraint_decl		: constraint_def
469			| validatetrans_def
470			;
471constraint_def		: CONSTRAIN names names cexpr ';'
472			{ if (define_constraint((constraint_expr_t*)$4)) return -1; }
473			;
474validatetrans_def	: VALIDATETRANS names cexpr ';'
475			{ if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
476			;
477cexpr			: '(' 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			;
491cexpr_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			;
564op			: EQUALS
565			{ $$ = CEXPR_EQ; }
566			| NOTEQUAL
567			{ $$ = CEXPR_NEQ; }
568			;
569role_mls_op		: op
570			{ $$ = $1; }
571			| DOM
572			{ $$ = CEXPR_DOM; }
573			| DOMBY
574			{ $$ = CEXPR_DOMBY; }
575			| INCOMP
576			{ $$ = CEXPR_INCOMP; }
577			;
578users			: user_def
579			| users user_def
580			;
581user_def		: USER identifier ROLES names opt_mls_user ';'
582	                {if (define_user()) return -1;}
583			;
584opt_mls_user		: LEVEL mls_level_def RANGE mls_range_def
585			|
586			;
587initial_sid_contexts	: initial_sid_context_def
588			| initial_sid_contexts initial_sid_context_def
589			;
590initial_sid_context_def	: SID identifier security_context_def
591			{if (define_initial_sid_context()) return -1;}
592			;
593opt_dev_contexts	: dev_contexts |
594			;
595dev_contexts		: dev_context_def
596			| dev_contexts dev_context_def
597			;
598dev_context_def		: pirq_context_def |
599			  iomem_context_def |
600			  ioport_context_def |
601			  pci_context_def
602			;
603pirq_context_def 	: PIRQCON number security_context_def
604		        {if (define_pirq_context($2)) return -1;}
605		        ;
606iomem_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		        ;
611ioport_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			;
616pci_context_def  	: PCIDEVICECON number security_context_def
617		        {if (define_pcidevice_context($2)) return -1;}
618		        ;
619opt_fs_contexts         : fs_contexts
620                        |
621                        ;
622fs_contexts		: fs_context_def
623			| fs_contexts fs_context_def
624			;
625fs_context_def		: FSCON number number security_context_def security_context_def
626			{if (define_fs_context($2,$3)) return -1;}
627			;
628net_contexts		: opt_port_contexts opt_netif_contexts opt_node_contexts
629			;
630opt_port_contexts       : port_contexts
631                        |
632                        ;
633port_contexts		: port_context_def
634			| port_contexts port_context_def
635			;
636port_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			;
641opt_netif_contexts      : netif_contexts
642                        |
643                        ;
644netif_contexts		: netif_context_def
645			| netif_contexts netif_context_def
646			;
647netif_context_def	: NETIFCON identifier security_context_def security_context_def
648			{if (define_netif_context()) return -1;}
649			;
650opt_node_contexts       : node_contexts
651                        |
652                        ;
653node_contexts		: node_context_def
654			| node_contexts node_context_def
655			;
656node_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			;
661opt_fs_uses             : fs_uses
662                        |
663                        ;
664fs_uses                 : fs_use_def
665                        | fs_uses fs_use_def
666                        ;
667fs_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                        ;
674opt_genfs_contexts      : genfs_contexts
675                        |
676                        ;
677genfs_contexts          : genfs_context_def
678                        | genfs_contexts genfs_context_def
679                        ;
680genfs_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			;
687ipv4_addr_def		: IPV4_ADDR
688			{ if (insert_id(yytext,0)) return -1; }
689			;
690security_context_def	: identifier ':' identifier ':' identifier opt_mls_range_def
691	                ;
692opt_mls_range_def	: ':' mls_range_def
693			|
694			;
695mls_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	                ;
700mls_level_def		: identifier ':' id_comma_list
701			{if (insert_separator(0)) return -1;}
702	                | identifier
703			{if (insert_separator(0)) return -1;}
704	                ;
705id_comma_list           : identifier
706			| id_comma_list ',' identifier
707			;
708tilde			: '~'
709			;
710asterisk		: '*'
711			;
712names           	: 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			;
728tilde_push              : tilde
729                        { if (insert_id("~", 1)) return -1; }
730			;
731asterisk_push           : asterisk
732                        { if (insert_id("*", 1)) return -1; }
733			;
734names_push		: identifier_push
735			| '{' identifier_list_push '}'
736			| asterisk_push
737			| tilde_push identifier_push
738			| tilde_push '{' identifier_list_push '}'
739			;
740identifier_list_push	: identifier_push
741			| identifier_list_push identifier_push
742			;
743identifier_push		: IDENTIFIER
744			{ if (insert_id(yytext, 1)) return -1; }
745			;
746identifier_list		: identifier
747			| identifier_list identifier
748			;
749nested_id_set           : '{' nested_id_list '}'
750                        ;
751nested_id_list          : nested_id_element | nested_id_list nested_id_element
752                        ;
753nested_id_element       : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
754                        ;
755identifier		: IDENTIFIER
756			{ if (insert_id(yytext,0)) return -1; }
757			;
758filesystem		: FILESYSTEM
759                        { if (insert_id(yytext,0)) return -1; }
760                        | IDENTIFIER
761			{ if (insert_id(yytext,0)) return -1; }
762                        ;
763path     		: PATH
764			{ if (insert_id(yytext,0)) return -1; }
765			;
766filename		: FILENAME
767			{ yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
768			;
769number			: NUMBER
770			{ $$ = strtoul(yytext,NULL,0); }
771			;
772ipv6_addr		: IPV6_ADDR
773			{ if (insert_id(yytext,0)) return -1; }
774			;
775policycap_def		: POLICYCAP identifier ';'
776			{if (define_polcap()) return -1;}
777			;
778permissive_def		: PERMISSIVE identifier ';'
779			{if (define_permissive()) return -1;}
780
781/*********** module grammar below ***********/
782
783module_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                        ;
788module_def              : MODULE identifier version_identifier ';'
789                        { if (define_policy(pass, 1) == -1) return -1; }
790                        ;
791version_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                        ;
797avrules_block           : avrule_decls avrule_user_defs
798                        ;
799avrule_decls            : avrule_decls avrule_decl
800                        | avrule_decl
801                        ;
802avrule_decl             : rbac_decl
803                        | te_decl
804                        | cond_stmt_def
805                        | require_block
806                        | optional_block
807                        | ';'
808                        ;
809require_block           : REQUIRE '{' require_list '}'
810                        ;
811require_list            : require_list require_decl
812                        | require_decl
813                        ;
814require_decl            : require_class ';'
815                        | require_decl_def require_id_list ';'
816                        ;
817require_class           : CLASS identifier names
818                        { if (require_class(pass)) return -1; }
819                        ;
820require_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                        ;
830require_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                        ;
835optional_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                        ;
840optional_else           : else_decl '{' avrules_block '}'
841                        { if (end_avrule_block(pass) == -1) return -1; }
842                        | /* empty */
843                        ;
844optional_decl           : OPTIONAL
845                        { if (begin_optional(pass) == -1) return -1; }
846                        ;
847else_decl               : ELSE
848                        { if (begin_optional_else(pass) == -1) return -1; }
849                        ;
850avrule_user_defs        : user_def avrule_user_defs
851                        | /* empty */
852                        ;
853