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