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