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