blob: abb7d88557e44675a617f14f49d9e4dbd28e8d68 [file] [log] [blame]
Joshua Brindle13cd4c82008-08-19 15:30:36 -04001
2/*
Stephen Smalley53bb2a12017-08-17 14:16:06 -04003 * Author : Stephen Smalley, <sds@tycho.nsa.gov>
Joshua Brindle13cd4c82008-08-19 15:30:36 -04004 */
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.
Daniel Jurgens5b203142017-05-22 16:08:23 +030024 * Copyright (C) 2017 Mellanox Technologies Inc.
Joshua Brindle13cd4c82008-08-19 15:30:36 -040025 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation, version 2.
28 */
29
30/* FLASK */
31
32%{
33#include <sys/types.h>
34#include <assert.h>
35#include <stdarg.h>
36#include <stdint.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <sys/socket.h>
41#include <netinet/in.h>
42#include <arpa/inet.h>
43#include <stdlib.h>
44
45#include <sepol/policydb/expand.h>
46#include <sepol/policydb/policydb.h>
47#include <sepol/policydb/services.h>
48#include <sepol/policydb/conditional.h>
49#include <sepol/policydb/flask.h>
50#include <sepol/policydb/hierarchy.h>
51#include <sepol/policydb/polcaps.h>
52#include "queue.h"
53#include "checkpolicy.h"
54#include "module_compiler.h"
55#include "policy_define.h"
56
57extern policydb_t *policydbp;
58extern unsigned int pass;
59
60extern char yytext[];
61extern int yylex(void);
Nicolas Iooss832e7012014-09-14 23:41:39 +020062extern int yywarn(const char *msg);
63extern int yyerror(const char *msg);
Joshua Brindle13cd4c82008-08-19 15:30:36 -040064
Nicolas Ioossc4a4a1a2014-09-14 23:41:49 +020065typedef int (* require_func_t)(int pass);
Joshua Brindle13cd4c82008-08-19 15:30:36 -040066
67%}
68
69%union {
70 unsigned int val;
Daniel De Graaf82030de2015-03-17 16:43:23 -040071 uint64_t val64;
Joshua Brindle13cd4c82008-08-19 15:30:36 -040072 uintptr_t valptr;
73 void *ptr;
74 require_func_t require_func;
75}
76
77%type <ptr> cond_expr cond_expr_prim cond_pol_list cond_else
78%type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def
79%type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def
80%type <ptr> role_def roles
81%type <valptr> cexpr cexpr_prim op role_mls_op
82%type <val> ipv4_addr_def number
Daniel De Graaf82030de2015-03-17 16:43:23 -040083%type <val64> number64
Joshua Brindle13cd4c82008-08-19 15:30:36 -040084%type <require_func> require_decl_def
85
86%token PATH
Daniel De Graafaab2d9f2015-03-17 16:43:22 -040087%token QPATH
Steve Lawrenceb42e15f2011-05-16 08:40:00 -040088%token FILENAME
Joshua Brindle13cd4c82008-08-19 15:30:36 -040089%token CLONE
90%token COMMON
91%token CLASS
92%token CONSTRAIN
93%token VALIDATETRANS
94%token INHERITS
95%token SID
96%token ROLE
Harry Ciao16675b72011-07-25 09:23:54 +080097%token ROLEATTRIBUTE
98%token ATTRIBUTE_ROLE
Joshua Brindle13cd4c82008-08-19 15:30:36 -040099%token ROLES
100%token TYPEALIAS
101%token TYPEATTRIBUTE
Joshua Brindle45728402008-10-08 06:56:51 -0400102%token TYPEBOUNDS
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400103%token TYPE
104%token TYPES
105%token ALIAS
106%token ATTRIBUTE
Jeff Vander Stoep10896652017-05-04 14:36:49 -0700107%token EXPANDATTRIBUTE
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400108%token BOOL
Harry Ciao80f26c52011-09-01 11:29:41 +0800109%token TUNABLE
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400110%token IF
111%token ELSE
112%token TYPE_TRANSITION
113%token TYPE_MEMBER
114%token TYPE_CHANGE
115%token ROLE_TRANSITION
116%token RANGE_TRANSITION
117%token SENSITIVITY
118%token DOMINANCE
119%token DOM DOMBY INCOMP
120%token CATEGORY
121%token LEVEL
122%token RANGE
123%token MLSCONSTRAIN
124%token MLSVALIDATETRANS
125%token USER
126%token NEVERALLOW
127%token ALLOW
128%token AUDITALLOW
129%token AUDITDENY
130%token DONTAUDIT
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700131%token ALLOWXPERM
132%token AUDITALLOWXPERM
133%token DONTAUDITXPERM
Jeff Vander Stoep99fc1772015-09-18 12:57:56 -0700134%token NEVERALLOWXPERM
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400135%token SOURCE
136%token TARGET
137%token SAMEUSER
138%token FSCON PORTCON NETIFCON NODECON
Daniel Jurgens5b203142017-05-22 16:08:23 +0300139%token IBPKEYCON
Daniel Jurgens5bc05dd2017-05-22 16:08:26 +0300140%token IBENDPORTCON
Daniel De Graaff0290672015-03-17 16:43:24 -0400141%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400142%token FSUSEXATTR FSUSETASK FSUSETRANS
143%token GENFSCON
144%token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
145%token NOT AND OR XOR
146%token CTRUE CFALSE
147%token IDENTIFIER
148%token NUMBER
149%token EQUALS
150%token NOTEQUAL
151%token IPV4_ADDR
152%token IPV6_ADDR
153%token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
154%token POLICYCAP
155%token PERMISSIVE
James Carter17ac87c2011-01-12 16:29:02 -0500156%token FILESYSTEM
Eric Paris693f5242012-12-18 11:41:25 -0500157%token DEFAULT_USER DEFAULT_ROLE DEFAULT_TYPE DEFAULT_RANGE
Joshua Brindle9ba35fe2019-09-09 11:05:57 -0700158%token LOW_HIGH LOW HIGH GLBLUB
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400159
160%left OR
161%left XOR
162%left AND
163%right NOT
164%left EQUALS NOTEQUAL
165%%
166policy : base_policy
167 | module_policy
168 ;
169base_policy : { if (define_policy(pass, 0) == -1) return -1; }
170 classes initial_sids access_vectors
171 { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; }
172 else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1; }}
Eric Paris09c783c2011-12-05 13:28:51 -0500173 opt_default_rules opt_mls te_rbac users opt_constraints
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400174 { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
175 else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
Daniel Jurgens5bc05dd2017-05-22 16:08:26 +0300176 initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts opt_ibpkey_contexts opt_ibendport_contexts
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400177 ;
178classes : class_def
179 | classes class_def
180 ;
181class_def : CLASS identifier
182 {if (define_class()) return -1;}
183 ;
184initial_sids : initial_sid_def
185 | initial_sids initial_sid_def
186 ;
187initial_sid_def : SID identifier
188 {if (define_initial_sid()) return -1;}
189 ;
190access_vectors : opt_common_perms av_perms
191 ;
192opt_common_perms : common_perms
193 |
194 ;
195common_perms : common_perms_def
196 | common_perms common_perms_def
197 ;
198common_perms_def : COMMON identifier '{' identifier_list '}'
199 {if (define_common_perms()) return -1;}
200 ;
201av_perms : av_perms_def
202 | av_perms av_perms_def
203 ;
204av_perms_def : CLASS identifier '{' identifier_list '}'
205 {if (define_av_perms(FALSE)) return -1;}
206 | CLASS identifier INHERITS identifier
207 {if (define_av_perms(TRUE)) return -1;}
208 | CLASS identifier INHERITS identifier '{' identifier_list '}'
209 {if (define_av_perms(TRUE)) return -1;}
210 ;
Eric Paris09c783c2011-12-05 13:28:51 -0500211opt_default_rules : default_rules
212 |
213 ;
214default_rules : default_user_def
215 | default_role_def
Eric Paris693f5242012-12-18 11:41:25 -0500216 | default_type_def
Eric Paris09c783c2011-12-05 13:28:51 -0500217 | default_range_def
218 | default_rules default_user_def
219 | default_rules default_role_def
Eric Paris693f5242012-12-18 11:41:25 -0500220 | default_rules default_type_def
Eric Paris09c783c2011-12-05 13:28:51 -0500221 | default_rules default_range_def
222 ;
223default_user_def : DEFAULT_USER names SOURCE ';'
224 {if (define_default_user(DEFAULT_SOURCE)) return -1; }
225 | DEFAULT_USER names TARGET ';'
226 {if (define_default_user(DEFAULT_TARGET)) return -1; }
227 ;
228default_role_def : DEFAULT_ROLE names SOURCE ';'
229 {if (define_default_role(DEFAULT_SOURCE)) return -1; }
230 | DEFAULT_ROLE names TARGET ';'
231 {if (define_default_role(DEFAULT_TARGET)) return -1; }
232 ;
Eric Paris693f5242012-12-18 11:41:25 -0500233default_type_def : DEFAULT_TYPE names SOURCE ';'
234 {if (define_default_type(DEFAULT_SOURCE)) return -1; }
235 | DEFAULT_TYPE names TARGET ';'
236 {if (define_default_type(DEFAULT_TARGET)) return -1; }
237 ;
Eric Paris09c783c2011-12-05 13:28:51 -0500238default_range_def : DEFAULT_RANGE names SOURCE LOW ';'
239 {if (define_default_range(DEFAULT_SOURCE_LOW)) return -1; }
240 | DEFAULT_RANGE names SOURCE HIGH ';'
241 {if (define_default_range(DEFAULT_SOURCE_HIGH)) return -1; }
242 | DEFAULT_RANGE names SOURCE LOW_HIGH ';'
243 {if (define_default_range(DEFAULT_SOURCE_LOW_HIGH)) return -1; }
244 | DEFAULT_RANGE names TARGET LOW ';'
245 {if (define_default_range(DEFAULT_TARGET_LOW)) return -1; }
246 | DEFAULT_RANGE names TARGET HIGH ';'
247 {if (define_default_range(DEFAULT_TARGET_HIGH)) return -1; }
248 | DEFAULT_RANGE names TARGET LOW_HIGH ';'
249 {if (define_default_range(DEFAULT_TARGET_LOW_HIGH)) return -1; }
Joshua Brindle9ba35fe2019-09-09 11:05:57 -0700250 | DEFAULT_RANGE names GLBLUB';'
251 {if (define_default_range(DEFAULT_GLBLUB)) return -1; }
Eric Paris09c783c2011-12-05 13:28:51 -0500252 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400253opt_mls : mls
254 |
255 ;
256mls : sensitivities dominance opt_categories levels mlspolicy
257 ;
258sensitivities : sensitivity_def
259 | sensitivities sensitivity_def
260 ;
261sensitivity_def : SENSITIVITY identifier alias_def ';'
262 {if (define_sens()) return -1;}
263 | SENSITIVITY identifier ';'
264 {if (define_sens()) return -1;}
265 ;
266alias_def : ALIAS names
267 ;
268dominance : DOMINANCE identifier
269 {if (define_dominance()) return -1;}
270 | DOMINANCE '{' identifier_list '}'
271 {if (define_dominance()) return -1;}
272 ;
273opt_categories : categories
274 |
275 ;
276categories : category_def
277 | categories category_def
278 ;
279category_def : CATEGORY identifier alias_def ';'
280 {if (define_category()) return -1;}
281 | CATEGORY identifier ';'
282 {if (define_category()) return -1;}
283 ;
284levels : level_def
285 | levels level_def
286 ;
287level_def : LEVEL identifier ':' id_comma_list ';'
288 {if (define_level()) return -1;}
289 | LEVEL identifier ';'
290 {if (define_level()) return -1;}
291 ;
292mlspolicy : mlspolicy_decl
293 | mlspolicy mlspolicy_decl
294 ;
295mlspolicy_decl : mlsconstraint_def
296 | mlsvalidatetrans_def
297 ;
298mlsconstraint_def : MLSCONSTRAIN names names cexpr ';'
299 { if (define_constraint((constraint_expr_t*)$4)) return -1; }
300 ;
301mlsvalidatetrans_def : MLSVALIDATETRANS names cexpr ';'
302 { if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
303 ;
304te_rbac : te_rbac_decl
305 | te_rbac te_rbac_decl
306 ;
307te_rbac_decl : te_decl
308 | rbac_decl
309 | cond_stmt_def
310 | optional_block
311 | policycap_def
312 | ';'
313 ;
Harry Ciao16675b72011-07-25 09:23:54 +0800314rbac_decl : attribute_role_def
315 | role_type_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400316 | role_dominance
317 | role_trans_def
318 | role_allow_def
Harry Ciao16675b72011-07-25 09:23:54 +0800319 | roleattribute_def
320 | role_attr_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400321 ;
322te_decl : attribute_def
Jeff Vander Stoep10896652017-05-04 14:36:49 -0700323 | expandattribute_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400324 | type_def
325 | typealias_def
326 | typeattribute_def
Joshua Brindle45728402008-10-08 06:56:51 -0400327 | typebounds_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400328 | bool_def
Harry Ciao80f26c52011-09-01 11:29:41 +0800329 | tunable_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400330 | transition_def
331 | range_trans_def
332 | te_avtab_def
333 | permissive_def
334 ;
335attribute_def : ATTRIBUTE identifier ';'
336 { if (define_attrib()) return -1;}
337 ;
Jeff Vander Stoep10896652017-05-04 14:36:49 -0700338expandattribute_def : EXPANDATTRIBUTE names bool_val ';'
339 { if (expand_attrib()) return -1;}
340 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400341type_def : TYPE identifier alias_def opt_attr_list ';'
342 {if (define_type(1)) return -1;}
343 | TYPE identifier opt_attr_list ';'
344 {if (define_type(0)) return -1;}
345 ;
346typealias_def : TYPEALIAS identifier alias_def ';'
347 {if (define_typealias()) return -1;}
348 ;
349typeattribute_def : TYPEATTRIBUTE identifier id_comma_list ';'
350 {if (define_typeattribute()) return -1;}
351 ;
Joshua Brindle45728402008-10-08 06:56:51 -0400352typebounds_def : TYPEBOUNDS identifier id_comma_list ';'
353 {if (define_typebounds()) return -1;}
354 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400355opt_attr_list : ',' id_comma_list
356 |
357 ;
358bool_def : BOOL identifier bool_val ';'
Harry Ciao80f26c52011-09-01 11:29:41 +0800359 { if (define_bool_tunable(0)) return -1; }
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400360 ;
Harry Ciao80f26c52011-09-01 11:29:41 +0800361tunable_def : TUNABLE identifier bool_val ';'
362 { if (define_bool_tunable(1)) return -1; }
363 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400364bool_val : CTRUE
365 { if (insert_id("T",0)) return -1; }
366 | CFALSE
367 { if (insert_id("F",0)) return -1; }
368 ;
369cond_stmt_def : IF cond_expr '{' cond_pol_list '}' cond_else
370 { if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (avrule_t*)$4, (avrule_t*)$6) < 0) return -1; }}
371 ;
372cond_else : ELSE '{' cond_pol_list '}'
373 { $$ = $3; }
374 | /* empty */
375 { $$ = NULL; }
Scapelli387dc632014-09-18 15:47:45 +0200376 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400377cond_expr : '(' cond_expr ')'
378 { $$ = $2;}
379 | NOT cond_expr
380 { $$ = define_cond_expr(COND_NOT, $2, 0);
381 if ($$ == 0) return -1; }
382 | cond_expr AND cond_expr
383 { $$ = define_cond_expr(COND_AND, $1, $3);
384 if ($$ == 0) return -1; }
385 | cond_expr OR cond_expr
386 { $$ = define_cond_expr(COND_OR, $1, $3);
387 if ($$ == 0) return -1; }
388 | cond_expr XOR cond_expr
389 { $$ = define_cond_expr(COND_XOR, $1, $3);
390 if ($$ == 0) return -1; }
391 | cond_expr EQUALS cond_expr
392 { $$ = define_cond_expr(COND_EQ, $1, $3);
393 if ($$ == 0) return -1; }
394 | cond_expr NOTEQUAL cond_expr
395 { $$ = define_cond_expr(COND_NEQ, $1, $3);
396 if ($$ == 0) return -1; }
397 | cond_expr_prim
398 { $$ = $1; }
399 ;
400cond_expr_prim : identifier
401 { $$ = define_cond_expr(COND_BOOL,0, 0);
402 if ($$ == COND_ERR) return -1; }
403 ;
404cond_pol_list : cond_pol_list cond_rule_def
405 { $$ = define_cond_pol_list((avrule_t *)$1, (avrule_t *)$2); }
406 | /* empty */
407 { $$ = NULL; }
408 ;
409cond_rule_def : cond_transition_def
410 { $$ = $1; }
411 | cond_te_avtab_def
412 { $$ = $1; }
413 | require_block
414 { $$ = NULL; }
415 ;
Steve Lawrenceb42e15f2011-05-16 08:40:00 -0400416cond_transition_def : TYPE_TRANSITION names names ':' names identifier filename ';'
Eric Paris516cb2a2011-03-28 14:00:19 -0400417 { $$ = define_cond_filename_trans() ;
418 if ($$ == COND_ERR) return -1;}
419 | TYPE_TRANSITION names names ':' names identifier ';'
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400420 { $$ = define_cond_compute_type(AVRULE_TRANSITION) ;
421 if ($$ == COND_ERR) return -1;}
422 | TYPE_MEMBER names names ':' names identifier ';'
423 { $$ = define_cond_compute_type(AVRULE_MEMBER) ;
424 if ($$ == COND_ERR) return -1;}
425 | TYPE_CHANGE names names ':' names identifier ';'
426 { $$ = define_cond_compute_type(AVRULE_CHANGE) ;
427 if ($$ == COND_ERR) return -1;}
428 ;
429cond_te_avtab_def : cond_allow_def
430 { $$ = $1; }
431 | cond_auditallow_def
432 { $$ = $1; }
433 | cond_auditdeny_def
434 { $$ = $1; }
435 | cond_dontaudit_def
436 { $$ = $1; }
437 ;
438cond_allow_def : ALLOW names names ':' names names ';'
439 { $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
440 if ($$ == COND_ERR) return -1; }
441 ;
442cond_auditallow_def : AUDITALLOW names names ':' names names ';'
443 { $$ = define_cond_te_avtab(AVRULE_AUDITALLOW) ;
444 if ($$ == COND_ERR) return -1; }
445 ;
446cond_auditdeny_def : AUDITDENY names names ':' names names ';'
447 { $$ = define_cond_te_avtab(AVRULE_AUDITDENY) ;
448 if ($$ == COND_ERR) return -1; }
449 ;
450cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
451 { $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
452 if ($$ == COND_ERR) return -1; }
453 ;
Eric Parisfdeecca2011-11-02 13:03:59 -0400454 ;
Steve Lawrenceb42e15f2011-05-16 08:40:00 -0400455transition_def : TYPE_TRANSITION names names ':' names identifier filename ';'
Steve Lawrencecb271f72011-05-16 08:38:37 -0400456 {if (define_filename_trans()) return -1; }
457 | TYPE_TRANSITION names names ':' names identifier ';'
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400458 {if (define_compute_type(AVRULE_TRANSITION)) return -1;}
459 | TYPE_MEMBER names names ':' names identifier ';'
460 {if (define_compute_type(AVRULE_MEMBER)) return -1;}
461 | TYPE_CHANGE names names ':' names identifier ';'
462 {if (define_compute_type(AVRULE_CHANGE)) return -1;}
463 ;
464range_trans_def : RANGE_TRANSITION names names mls_range_def ';'
465 { if (define_range_trans(0)) return -1; }
466 | RANGE_TRANSITION names names ':' names mls_range_def ';'
467 { if (define_range_trans(1)) return -1; }
468 ;
469te_avtab_def : allow_def
470 | auditallow_def
471 | auditdeny_def
472 | dontaudit_def
473 | neverallow_def
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700474 | xperm_allow_def
475 | xperm_auditallow_def
476 | xperm_dontaudit_def
Jeff Vander Stoep99fc1772015-09-18 12:57:56 -0700477 | xperm_neverallow_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400478 ;
479allow_def : ALLOW names names ':' names names ';'
480 {if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
481 ;
482auditallow_def : AUDITALLOW names names ':' names names ';'
483 {if (define_te_avtab(AVRULE_AUDITALLOW)) return -1; }
484 ;
485auditdeny_def : AUDITDENY names names ':' names names ';'
486 {if (define_te_avtab(AVRULE_AUDITDENY)) return -1; }
487 ;
488dontaudit_def : DONTAUDIT names names ':' names names ';'
489 {if (define_te_avtab(AVRULE_DONTAUDIT)) return -1; }
490 ;
491neverallow_def : NEVERALLOW names names ':' names names ';'
492 {if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
493 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700494xperm_allow_def : ALLOWXPERM names names ':' names identifier xperms ';'
495 {if (define_te_avtab_extended_perms(AVRULE_XPERMS_ALLOWED)) return -1; }
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700496 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700497xperm_auditallow_def : AUDITALLOWXPERM names names ':' names identifier xperms ';'
498 {if (define_te_avtab_extended_perms(AVRULE_XPERMS_AUDITALLOW)) return -1; }
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700499 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700500xperm_dontaudit_def : DONTAUDITXPERM names names ':' names identifier xperms ';'
501 {if (define_te_avtab_extended_perms(AVRULE_XPERMS_DONTAUDIT)) return -1; }
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700502 ;
Jeff Vander Stoep99fc1772015-09-18 12:57:56 -0700503xperm_neverallow_def : NEVERALLOWXPERM names names ':' names identifier xperms ';'
504 {if (define_te_avtab_extended_perms(AVRULE_XPERMS_NEVERALLOW)) return -1; }
505 ;
Harry Ciao16675b72011-07-25 09:23:54 +0800506attribute_role_def : ATTRIBUTE_ROLE identifier ';'
507 {if (define_attrib_role()) return -1; }
Dan Walsh56196352011-08-09 10:28:38 -0400508 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400509role_type_def : ROLE identifier TYPES names ';'
510 {if (define_role_types()) return -1;}
Harry Ciao16675b72011-07-25 09:23:54 +0800511 ;
512role_attr_def : ROLE identifier opt_attr_list ';'
513 {if (define_role_attr()) return -1;}
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400514 ;
515role_dominance : DOMINANCE '{' roles '}'
516 ;
517role_trans_def : ROLE_TRANSITION names names identifier ';'
Harry Ciaoe95f3582011-03-25 13:51:59 +0800518 {if (define_role_trans(0)) return -1; }
519 | ROLE_TRANSITION names names ':' names identifier ';'
520 {if (define_role_trans(1)) return -1;}
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400521 ;
522role_allow_def : ALLOW names names ';'
523 {if (define_role_allow()) return -1; }
524 ;
525roles : role_def
526 { $$ = $1; }
527 | roles role_def
528 { $$ = merge_roles_dom((role_datum_t*)$1, (role_datum_t*)$2); if ($$ == 0) return -1;}
529 ;
530role_def : ROLE identifier_push ';'
531 {$$ = define_role_dom(NULL); if ($$ == 0) return -1;}
532 | ROLE identifier_push '{' roles '}'
533 {$$ = define_role_dom((role_datum_t*)$4); if ($$ == 0) return -1;}
534 ;
Harry Ciao16675b72011-07-25 09:23:54 +0800535roleattribute_def : ROLEATTRIBUTE identifier id_comma_list ';'
536 {if (define_roleattribute()) return -1;}
537 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400538opt_constraints : constraints
539 |
540 ;
541constraints : constraint_decl
542 | constraints constraint_decl
543 ;
544constraint_decl : constraint_def
545 | validatetrans_def
546 ;
547constraint_def : CONSTRAIN names names cexpr ';'
548 { if (define_constraint((constraint_expr_t*)$4)) return -1; }
549 ;
550validatetrans_def : VALIDATETRANS names cexpr ';'
551 { if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
552 ;
553cexpr : '(' cexpr ')'
554 { $$ = $2; }
555 | NOT cexpr
556 { $$ = define_cexpr(CEXPR_NOT, $2, 0);
557 if ($$ == 0) return -1; }
558 | cexpr AND cexpr
559 { $$ = define_cexpr(CEXPR_AND, $1, $3);
560 if ($$ == 0) return -1; }
561 | cexpr OR cexpr
562 { $$ = define_cexpr(CEXPR_OR, $1, $3);
563 if ($$ == 0) return -1; }
564 | cexpr_prim
565 { $$ = $1; }
566 ;
567cexpr_prim : U1 op U2
568 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, $2);
569 if ($$ == 0) return -1; }
570 | R1 role_mls_op R2
571 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
572 if ($$ == 0) return -1; }
573 | T1 op T2
574 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_TYPE, $2);
575 if ($$ == 0) return -1; }
576 | U1 op { if (insert_separator(1)) return -1; } names_push
577 { $$ = define_cexpr(CEXPR_NAMES, CEXPR_USER, $2);
578 if ($$ == 0) return -1; }
579 | U2 op { if (insert_separator(1)) return -1; } names_push
580 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_TARGET), $2);
581 if ($$ == 0) return -1; }
582 | U3 op { if (insert_separator(1)) return -1; } names_push
583 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_XTARGET), $2);
584 if ($$ == 0) return -1; }
585 | R1 op { if (insert_separator(1)) return -1; } names_push
586 { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, $2);
587 if ($$ == 0) return -1; }
588 | R2 op { if (insert_separator(1)) return -1; } names_push
589 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), $2);
590 if ($$ == 0) return -1; }
591 | R3 op { if (insert_separator(1)) return -1; } names_push
592 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
593 if ($$ == 0) return -1; }
594 | T1 op { if (insert_separator(1)) return -1; } names_push
595 { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
596 if ($$ == 0) return -1; }
597 | T2 op { if (insert_separator(1)) return -1; } names_push
598 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
599 if ($$ == 0) return -1; }
600 | T3 op { if (insert_separator(1)) return -1; } names_push
601 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
602 if ($$ == 0) return -1; }
603 | SAMEUSER
604 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, CEXPR_EQ);
605 if ($$ == 0) return -1; }
606 | SOURCE ROLE { if (insert_separator(1)) return -1; } names_push
607 { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, CEXPR_EQ);
608 if ($$ == 0) return -1; }
609 | TARGET ROLE { if (insert_separator(1)) return -1; } names_push
610 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), CEXPR_EQ);
611 if ($$ == 0) return -1; }
612 | ROLE role_mls_op
613 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
614 if ($$ == 0) return -1; }
615 | SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
616 { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
617 if ($$ == 0) return -1; }
618 | TARGET TYPE { if (insert_separator(1)) return -1; } names_push
619 { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
620 if ($$ == 0) return -1; }
621 | L1 role_mls_op L2
622 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1L2, $2);
623 if ($$ == 0) return -1; }
624 | L1 role_mls_op H2
625 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H2, $2);
626 if ($$ == 0) return -1; }
627 | H1 role_mls_op L2
628 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1L2, $2);
629 if ($$ == 0) return -1; }
630 | H1 role_mls_op H2
631 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1H2, $2);
632 if ($$ == 0) return -1; }
633 | L1 role_mls_op H1
634 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H1, $2);
635 if ($$ == 0) return -1; }
636 | L2 role_mls_op H2
637 { $$ = define_cexpr(CEXPR_ATTR, CEXPR_L2H2, $2);
638 if ($$ == 0) return -1; }
639 ;
640op : EQUALS
641 { $$ = CEXPR_EQ; }
642 | NOTEQUAL
643 { $$ = CEXPR_NEQ; }
644 ;
645role_mls_op : op
646 { $$ = $1; }
647 | DOM
648 { $$ = CEXPR_DOM; }
649 | DOMBY
650 { $$ = CEXPR_DOMBY; }
651 | INCOMP
652 { $$ = CEXPR_INCOMP; }
653 ;
654users : user_def
655 | users user_def
656 ;
657user_def : USER identifier ROLES names opt_mls_user ';'
658 {if (define_user()) return -1;}
659 ;
660opt_mls_user : LEVEL mls_level_def RANGE mls_range_def
661 |
662 ;
663initial_sid_contexts : initial_sid_context_def
664 | initial_sid_contexts initial_sid_context_def
665 ;
666initial_sid_context_def : SID identifier security_context_def
667 {if (define_initial_sid_context()) return -1;}
668 ;
Paul Nuzzi79d10a82009-09-29 10:06:26 -0400669opt_dev_contexts : dev_contexts |
670 ;
671dev_contexts : dev_context_def
672 | dev_contexts dev_context_def
673 ;
674dev_context_def : pirq_context_def |
675 iomem_context_def |
676 ioport_context_def |
Daniel De Graaff0290672015-03-17 16:43:24 -0400677 pci_context_def |
678 dtree_context_def
Paul Nuzzi79d10a82009-09-29 10:06:26 -0400679 ;
680pirq_context_def : PIRQCON number security_context_def
681 {if (define_pirq_context($2)) return -1;}
682 ;
Daniel De Graaf82030de2015-03-17 16:43:23 -0400683iomem_context_def : IOMEMCON number64 security_context_def
Paul Nuzzi79d10a82009-09-29 10:06:26 -0400684 {if (define_iomem_context($2,$2)) return -1;}
Daniel De Graaf82030de2015-03-17 16:43:23 -0400685 | IOMEMCON number64 '-' number64 security_context_def
Paul Nuzzi79d10a82009-09-29 10:06:26 -0400686 {if (define_iomem_context($2,$4)) return -1;}
687 ;
688ioport_context_def : IOPORTCON number security_context_def
689 {if (define_ioport_context($2,$2)) return -1;}
690 | IOPORTCON number '-' number security_context_def
691 {if (define_ioport_context($2,$4)) return -1;}
692 ;
693pci_context_def : PCIDEVICECON number security_context_def
694 {if (define_pcidevice_context($2)) return -1;}
695 ;
Daniel De Graaff0290672015-03-17 16:43:24 -0400696dtree_context_def : DEVICETREECON path security_context_def
697 {if (define_devicetree_context()) return -1;}
698 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400699opt_fs_contexts : fs_contexts
700 |
701 ;
702fs_contexts : fs_context_def
703 | fs_contexts fs_context_def
704 ;
705fs_context_def : FSCON number number security_context_def security_context_def
706 {if (define_fs_context($2,$3)) return -1;}
707 ;
Daniel Jurgens5bc05dd2017-05-22 16:08:26 +0300708net_contexts : opt_port_contexts opt_netif_contexts opt_node_contexts
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400709 ;
710opt_port_contexts : port_contexts
711 |
712 ;
713port_contexts : port_context_def
714 | port_contexts port_context_def
715 ;
716port_context_def : PORTCON identifier number security_context_def
717 {if (define_port_context($3,$3)) return -1;}
718 | PORTCON identifier number '-' number security_context_def
719 {if (define_port_context($3,$5)) return -1;}
720 ;
Daniel Jurgens5b203142017-05-22 16:08:23 +0300721opt_ibpkey_contexts : ibpkey_contexts
722 |
723 ;
724ibpkey_contexts : ibpkey_context_def
725 | ibpkey_contexts ibpkey_context_def
726 ;
727ibpkey_context_def : IBPKEYCON ipv6_addr number security_context_def
728 {if (define_ibpkey_context($3,$3)) return -1;}
729 | IBPKEYCON ipv6_addr number '-' number security_context_def
730 {if (define_ibpkey_context($3,$5)) return -1;}
731 ;
Daniel Jurgens5bc05dd2017-05-22 16:08:26 +0300732opt_ibendport_contexts : ibendport_contexts
733 |
734 ;
735ibendport_contexts : ibendport_context_def
736 | ibendport_contexts ibendport_context_def
737 ;
738ibendport_context_def : IBENDPORTCON identifier number security_context_def
739 {if (define_ibendport_context($3)) return -1;}
740 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400741opt_netif_contexts : netif_contexts
742 |
743 ;
744netif_contexts : netif_context_def
745 | netif_contexts netif_context_def
746 ;
747netif_context_def : NETIFCON identifier security_context_def security_context_def
748 {if (define_netif_context()) return -1;}
749 ;
750opt_node_contexts : node_contexts
751 |
752 ;
753node_contexts : node_context_def
754 | node_contexts node_context_def
755 ;
756node_context_def : NODECON ipv4_addr_def ipv4_addr_def security_context_def
757 {if (define_ipv4_node_context()) return -1;}
758 | NODECON ipv6_addr ipv6_addr security_context_def
759 {if (define_ipv6_node_context()) return -1;}
760 ;
761opt_fs_uses : fs_uses
762 |
763 ;
764fs_uses : fs_use_def
765 | fs_uses fs_use_def
766 ;
Eric Parisfdeecca2011-11-02 13:03:59 -0400767fs_use_def : FSUSEXATTR filesystem security_context_def ';'
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400768 {if (define_fs_use(SECURITY_FS_USE_XATTR)) return -1;}
769 | FSUSETASK identifier security_context_def ';'
770 {if (define_fs_use(SECURITY_FS_USE_TASK)) return -1;}
771 | FSUSETRANS identifier security_context_def ';'
772 {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
773 ;
774opt_genfs_contexts : genfs_contexts
775 |
776 ;
777genfs_contexts : genfs_context_def
778 | genfs_contexts genfs_context_def
779 ;
Eric Parisfdeecca2011-11-02 13:03:59 -0400780genfs_context_def : GENFSCON filesystem path '-' identifier security_context_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400781 {if (define_genfs_context(1)) return -1;}
Eric Parisfdeecca2011-11-02 13:03:59 -0400782 | GENFSCON filesystem path '-' '-' {insert_id("-", 0);} security_context_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400783 {if (define_genfs_context(1)) return -1;}
Eric Parisfdeecca2011-11-02 13:03:59 -0400784 | GENFSCON filesystem path security_context_def
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400785 {if (define_genfs_context(0)) return -1;}
786 ;
787ipv4_addr_def : IPV4_ADDR
788 { if (insert_id(yytext,0)) return -1; }
789 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700790xperms : xperm
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700791 { if (insert_separator(0)) return -1; }
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700792 | nested_xperm_set
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700793 { if (insert_separator(0)) return -1; }
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700794 | tilde xperm
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700795 { if (insert_id("~", 0)) return -1; }
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700796 | tilde nested_xperm_set
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700797 { if (insert_id("~", 0)) return -1;
798 if (insert_separator(0)) return -1; }
799 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700800nested_xperm_set : '{' nested_xperm_list '}'
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700801 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700802nested_xperm_list : nested_xperm_element
803 | nested_xperm_list nested_xperm_element
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700804 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700805nested_xperm_element: xperm '-' { if (insert_id("-", 0)) return -1; } xperm
806 | xperm
807 | nested_xperm_set
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700808 ;
Jeff Vander Stoep915fa8f2015-06-12 09:01:12 -0700809xperm : number
Jeff Vander Stoep80bc7ee2015-04-22 13:53:25 -0700810 { if (insert_id(yytext,0)) return -1; }
811 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400812security_context_def : identifier ':' identifier ':' identifier opt_mls_range_def
813 ;
814opt_mls_range_def : ':' mls_range_def
815 |
816 ;
817mls_range_def : mls_level_def '-' mls_level_def
818 {if (insert_separator(0)) return -1;}
819 | mls_level_def
820 {if (insert_separator(0)) return -1;}
821 ;
822mls_level_def : identifier ':' id_comma_list
823 {if (insert_separator(0)) return -1;}
824 | identifier
825 {if (insert_separator(0)) return -1;}
826 ;
827id_comma_list : identifier
828 | id_comma_list ',' identifier
829 ;
830tilde : '~'
831 ;
832asterisk : '*'
833 ;
834names : identifier
835 { if (insert_separator(0)) return -1; }
836 | nested_id_set
837 { if (insert_separator(0)) return -1; }
838 | asterisk
839 { if (insert_id("*", 0)) return -1;
840 if (insert_separator(0)) return -1; }
841 | tilde identifier
842 { if (insert_id("~", 0)) return -1;
843 if (insert_separator(0)) return -1; }
844 | tilde nested_id_set
845 { if (insert_id("~", 0)) return -1;
846 if (insert_separator(0)) return -1; }
847 | identifier '-' { if (insert_id("-", 0)) return -1; } identifier
848 { if (insert_separator(0)) return -1; }
849 ;
850tilde_push : tilde
851 { if (insert_id("~", 1)) return -1; }
852 ;
853asterisk_push : asterisk
854 { if (insert_id("*", 1)) return -1; }
855 ;
856names_push : identifier_push
857 | '{' identifier_list_push '}'
858 | asterisk_push
859 | tilde_push identifier_push
860 | tilde_push '{' identifier_list_push '}'
861 ;
862identifier_list_push : identifier_push
863 | identifier_list_push identifier_push
864 ;
865identifier_push : IDENTIFIER
866 { if (insert_id(yytext, 1)) return -1; }
867 ;
868identifier_list : identifier
869 | identifier_list identifier
870 ;
871nested_id_set : '{' nested_id_list '}'
872 ;
873nested_id_list : nested_id_element | nested_id_list nested_id_element
874 ;
875nested_id_element : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
876 ;
877identifier : IDENTIFIER
878 { if (insert_id(yytext,0)) return -1; }
879 ;
Eric Parisfdeecca2011-11-02 13:03:59 -0400880filesystem : FILESYSTEM
881 { if (insert_id(yytext,0)) return -1; }
Dan Walshd72a9ec2011-04-12 09:54:46 -0400882 | IDENTIFIER
883 { if (insert_id(yytext,0)) return -1; }
884 ;
Eric Parisfdeecca2011-11-02 13:03:59 -0400885path : PATH
886 { if (insert_id(yytext,0)) return -1; }
Daniel De Graafaab2d9f2015-03-17 16:43:22 -0400887 | QPATH
888 { yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
Eric Parisfdeecca2011-11-02 13:03:59 -0400889 ;
890filename : FILENAME
891 { yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; }
892 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400893number : NUMBER
894 { $$ = strtoul(yytext,NULL,0); }
895 ;
Daniel De Graaf82030de2015-03-17 16:43:23 -0400896number64 : NUMBER
897 { $$ = strtoull(yytext,NULL,0); }
898 ;
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400899ipv6_addr : IPV6_ADDR
900 { if (insert_id(yytext,0)) return -1; }
901 ;
902policycap_def : POLICYCAP identifier ';'
903 {if (define_polcap()) return -1;}
904 ;
905permissive_def : PERMISSIVE identifier ';'
906 {if (define_permissive()) return -1;}
907
908/*********** module grammar below ***********/
909
910module_policy : module_def avrules_block
911 { if (end_avrule_block(pass) == -1) return -1;
912 if (policydb_index_others(NULL, policydbp, 0)) return -1;
913 }
914 ;
915module_def : MODULE identifier version_identifier ';'
916 { if (define_policy(pass, 1) == -1) return -1; }
917 ;
918version_identifier : VERSION_IDENTIFIER
919 { if (insert_id(yytext,0)) return -1; }
Daniel J Walshc61b6932011-04-29 15:41:16 -0400920 | number
921 { if (insert_id(yytext,0)) return -1; }
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400922 | ipv4_addr_def /* version can look like ipv4 address */
923 ;
924avrules_block : avrule_decls avrule_user_defs
925 ;
926avrule_decls : avrule_decls avrule_decl
927 | avrule_decl
928 ;
929avrule_decl : rbac_decl
930 | te_decl
931 | cond_stmt_def
932 | require_block
933 | optional_block
934 | ';'
935 ;
936require_block : REQUIRE '{' require_list '}'
937 ;
938require_list : require_list require_decl
939 | require_decl
940 ;
941require_decl : require_class ';'
942 | require_decl_def require_id_list ';'
943 ;
944require_class : CLASS identifier names
945 { if (require_class(pass)) return -1; }
946 ;
947require_decl_def : ROLE { $$ = require_role; }
948 | TYPE { $$ = require_type; }
949 | ATTRIBUTE { $$ = require_attribute; }
Harry Ciao16675b72011-07-25 09:23:54 +0800950 | ATTRIBUTE_ROLE { $$ = require_attribute_role; }
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400951 | USER { $$ = require_user; }
952 | BOOL { $$ = require_bool; }
Harry Ciao80f26c52011-09-01 11:29:41 +0800953 | TUNABLE { $$ = require_tunable; }
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400954 | SENSITIVITY { $$ = require_sens; }
955 | CATEGORY { $$ = require_cat; }
956 ;
957require_id_list : identifier
958 { if ($<require_func>0 (pass)) return -1; }
959 | require_id_list ',' identifier
960 { if ($<require_func>0 (pass)) return -1; }
961 ;
962optional_block : optional_decl '{' avrules_block '}'
963 { if (end_avrule_block(pass) == -1) return -1; }
964 optional_else
965 { if (end_optional(pass) == -1) return -1; }
966 ;
967optional_else : else_decl '{' avrules_block '}'
968 { if (end_avrule_block(pass) == -1) return -1; }
969 | /* empty */
970 ;
971optional_decl : OPTIONAL
972 { if (begin_optional(pass) == -1) return -1; }
973 ;
974else_decl : ELSE
975 { if (begin_optional_else(pass) == -1) return -1; }
976 ;
977avrule_user_defs : user_def avrule_user_defs
978 | /* empty */
979 ;