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