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