• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
3  */
4 
5 /*
6  * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
7  *
8  *	Support for enhanced MLS infrastructure.
9  *
10  * Updated: David Caplan, <dac@tresys.com>
11  *
12  * 	Added conditional policy language extensions
13  *
14  * Updated: Joshua Brindle <jbrindle@tresys.com>
15  *	    Karl MacMillan <kmacmillan@mentalrootkit.com>
16  *          Jason Tang     <jtang@tresys.com>
17  *
18  *	Added support for binary policy modules
19  *
20  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
21  * Copyright (C) 2003 - 2008 Tresys Technology, LLC
22  * Copyright (C) 2007 Red Hat Inc.
23  *	This program is free software; you can redistribute it and/or modify
24  *  	it under the terms of the GNU General Public License as published by
25  *	the Free Software Foundation, version 2.
26  */
27 
28 /* FLASK */
29 
30 #include <sys/types.h>
31 #include <assert.h>
32 #include <stdarg.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #include <stdlib.h>
41 
42 #include <sepol/policydb/expand.h>
43 #include <sepol/policydb/policydb.h>
44 #include <sepol/policydb/services.h>
45 #include <sepol/policydb/conditional.h>
46 #include <sepol/policydb/flask.h>
47 #include <sepol/policydb/hierarchy.h>
48 #include <sepol/policydb/polcaps.h>
49 #include "queue.h"
50 #include "checkpolicy.h"
51 #include "module_compiler.h"
52 #include "policy_define.h"
53 
54 policydb_t *policydbp;
55 queue_t id_queue = 0;
56 unsigned int pass;
57 char *curfile = 0;
58 int mlspol = 0;
59 
60 extern unsigned long policydb_lineno;
61 extern unsigned long source_lineno;
62 extern unsigned int policydb_errors;
63 
64 extern int yywarn(char *msg);
65 extern int yyerror(char *msg);
66 
67 #define ERRORMSG_LEN 255
68 static char errormsg[ERRORMSG_LEN + 1] = {0};
69 
70 static int id_has_dot(char *id);
71 static int parse_security_context(context_struct_t *c);
72 
73 /* initialize all of the state variables for the scanner/parser */
init_parser(int pass_number)74 void init_parser(int pass_number)
75 {
76 	policydb_lineno = 1;
77 	source_lineno = 1;
78 	policydb_errors = 0;
79 	pass = pass_number;
80 }
81 
yyerror2(char * fmt,...)82 void yyerror2(char *fmt, ...)
83 {
84 	va_list ap;
85 	va_start(ap, fmt);
86 	vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
87 	yyerror(errormsg);
88 	va_end(ap);
89 }
90 
insert_separator(int push)91 int insert_separator(int push)
92 {
93 	int error;
94 
95 	if (push)
96 		error = queue_push(id_queue, 0);
97 	else
98 		error = queue_insert(id_queue, 0);
99 
100 	if (error) {
101 		yyerror("queue overflow");
102 		return -1;
103 	}
104 	return 0;
105 }
106 
insert_id(char * id,int push)107 int insert_id(char *id, int push)
108 {
109 	char *newid = 0;
110 	int error;
111 
112 	newid = (char *)malloc(strlen(id) + 1);
113 	if (!newid) {
114 		yyerror("out of memory");
115 		return -1;
116 	}
117 	strcpy(newid, id);
118 	if (push)
119 		error = queue_push(id_queue, (queue_element_t) newid);
120 	else
121 		error = queue_insert(id_queue, (queue_element_t) newid);
122 
123 	if (error) {
124 		yyerror("queue overflow");
125 		free(newid);
126 		return -1;
127 	}
128 	return 0;
129 }
130 
131 /* If the identifier has a dot within it and that its first character
132    is not a dot then return 1, else return 0. */
id_has_dot(char * id)133 static int id_has_dot(char *id)
134 {
135 	if (strchr(id, '.') >= id + 1) {
136 		return 1;
137 	}
138 	return 0;
139 }
140 
define_class(void)141 int define_class(void)
142 {
143 	char *id = 0;
144 	class_datum_t *datum = 0;
145 	int ret;
146 	uint32_t value;
147 
148 	if (pass == 2) {
149 		id = queue_remove(id_queue);
150 		free(id);
151 		return 0;
152 	}
153 
154 	id = (char *)queue_remove(id_queue);
155 	if (!id) {
156 		yyerror("no class name for class definition?");
157 		return -1;
158 	}
159 	datum = (class_datum_t *) malloc(sizeof(class_datum_t));
160 	if (!datum) {
161 		yyerror("out of memory");
162 		goto bad;
163 	}
164 	memset(datum, 0, sizeof(class_datum_t));
165 	ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
166 	switch (ret) {
167 	case -3:{
168 			yyerror("Out of memory!");
169 			goto bad;
170 		}
171 	case -2:{
172 			yyerror2("duplicate declaration of class %s", id);
173 			goto bad;
174 		}
175 	case -1:{
176 			yyerror("could not declare class here");
177 			goto bad;
178 		}
179 	case 0:
180 	case 1:{
181 			break;
182 		}
183 	default:{
184 			assert(0);	/* should never get here */
185 		}
186 	}
187 	datum->s.value = value;
188 	return 0;
189 
190       bad:
191 	if (id)
192 		free(id);
193 	if (datum)
194 		free(datum);
195 	return -1;
196 }
197 
define_permissive(void)198 int define_permissive(void)
199 {
200 	char *type = NULL;
201 	struct type_datum *t;
202 	int rc = 0;
203 
204 	type = queue_remove(id_queue);
205 
206 	if (!type) {
207 		yyerror2("forgot to include type in permissive definition?");
208 		rc = -1;
209 		goto out;
210 	}
211 
212 	if (pass == 1)
213 		goto out;
214 
215 	if (!is_id_in_scope(SYM_TYPES, type)) {
216 		yyerror2("type %s is not within scope", type);
217 		rc = -1;
218 		goto out;
219 	}
220 
221 	t = hashtab_search(policydbp->p_types.table, type);
222 	if (!t) {
223 		yyerror2("type is not defined: %s", type);
224 		rc = -1;
225 		goto out;
226 	}
227 
228 	if (t->flavor == TYPE_ATTRIB) {
229 		yyerror2("attributes may not be permissive: %s\n", type);
230 		rc = -1;
231 		goto out;
232 	}
233 
234 	t->flags |= TYPE_FLAGS_PERMISSIVE;
235 
236 out:
237 	free(type);
238 	return rc;
239 }
240 
define_polcap(void)241 int define_polcap(void)
242 {
243 	char *id = 0;
244 	int capnum;
245 
246 	if (pass == 2) {
247 		id = queue_remove(id_queue);
248 		free(id);
249 		return 0;
250 	}
251 
252 	id = (char *)queue_remove(id_queue);
253 	if (!id) {
254 		yyerror("no capability name for policycap definition?");
255 		goto bad;
256 	}
257 
258 	/* Check for valid cap name -> number mapping */
259 	capnum = sepol_polcap_getnum(id);
260 	if (capnum < 0) {
261 		yyerror2("invalid policy capability name %s", id);
262 		goto bad;
263 	}
264 
265 	/* Store it */
266 	if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
267 		yyerror("out of memory");
268 		goto bad;
269 	}
270 
271 	free(id);
272 	return 0;
273 
274       bad:
275 	free(id);
276 	return -1;
277 }
278 
define_initial_sid(void)279 int define_initial_sid(void)
280 {
281 	char *id = 0;
282 	ocontext_t *newc = 0, *c, *head;
283 
284 	if (pass == 2) {
285 		id = queue_remove(id_queue);
286 		free(id);
287 		return 0;
288 	}
289 
290 	id = (char *)queue_remove(id_queue);
291 	if (!id) {
292 		yyerror("no sid name for SID definition?");
293 		return -1;
294 	}
295 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
296 	if (!newc) {
297 		yyerror("out of memory");
298 		goto bad;
299 	}
300 	memset(newc, 0, sizeof(ocontext_t));
301 	newc->u.name = id;
302 	context_init(&newc->context[0]);
303 	head = policydbp->ocontexts[OCON_ISID];
304 
305 	for (c = head; c; c = c->next) {
306 		if (!strcmp(newc->u.name, c->u.name)) {
307 			yyerror2("duplicate initial SID %s", id);
308 			goto bad;
309 		}
310 	}
311 
312 	if (head) {
313 		newc->sid[0] = head->sid[0] + 1;
314 	} else {
315 		newc->sid[0] = 1;
316 	}
317 	newc->next = head;
318 	policydbp->ocontexts[OCON_ISID] = newc;
319 
320 	return 0;
321 
322       bad:
323 	if (id)
324 		free(id);
325 	if (newc)
326 		free(newc);
327 	return -1;
328 }
329 
read_classes(ebitmap_t * e_classes)330 static int read_classes(ebitmap_t *e_classes)
331 {
332 	char *id;
333 	class_datum_t *cladatum;
334 
335 	while ((id = queue_remove(id_queue))) {
336 		if (!is_id_in_scope(SYM_CLASSES, id)) {
337 			yyerror2("class %s is not within scope", id);
338 			return -1;
339 		}
340 		cladatum = hashtab_search(policydbp->p_classes.table, id);
341 		if (!cladatum) {
342 			yyerror2("unknown class %s", id);
343 			return -1;
344 		}
345 		if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) {
346 			yyerror("Out of memory");
347 			return -1;
348 		}
349 		free(id);
350 	}
351 	return 0;
352 }
353 
define_default_user(int which)354 int define_default_user(int which)
355 {
356 	char *id;
357 	class_datum_t *cladatum;
358 
359 	if (pass == 1) {
360 		while ((id = queue_remove(id_queue)))
361 			free(id);
362 		return 0;
363 	}
364 
365 	while ((id = queue_remove(id_queue))) {
366 		if (!is_id_in_scope(SYM_CLASSES, id)) {
367 			yyerror2("class %s is not within scope", id);
368 			return -1;
369 		}
370 		cladatum = hashtab_search(policydbp->p_classes.table, id);
371 		if (!cladatum) {
372 			yyerror2("unknown class %s", id);
373 			return -1;
374 		}
375 		if (cladatum->default_user && cladatum->default_user != which) {
376 			yyerror2("conflicting default user information for class %s", id);
377 			return -1;
378 		}
379 		cladatum->default_user = which;
380 		free(id);
381 	}
382 
383 	return 0;
384 }
385 
define_default_role(int which)386 int define_default_role(int which)
387 {
388 	char *id;
389 	class_datum_t *cladatum;
390 
391 	if (pass == 1) {
392 		while ((id = queue_remove(id_queue)))
393 			free(id);
394 		return 0;
395 	}
396 
397 	while ((id = queue_remove(id_queue))) {
398 		if (!is_id_in_scope(SYM_CLASSES, id)) {
399 			yyerror2("class %s is not within scope", id);
400 			return -1;
401 		}
402 		cladatum = hashtab_search(policydbp->p_classes.table, id);
403 		if (!cladatum) {
404 			yyerror2("unknown class %s", id);
405 			return -1;
406 		}
407 		if (cladatum->default_role && cladatum->default_role != which) {
408 			yyerror2("conflicting default role information for class %s", id);
409 			return -1;
410 		}
411 		cladatum->default_role = which;
412 		free(id);
413 	}
414 
415 	return 0;
416 }
417 
define_default_range(int which)418 int define_default_range(int which)
419 {
420 	char *id;
421 	class_datum_t *cladatum;
422 
423 	if (pass == 1) {
424 		while ((id = queue_remove(id_queue)))
425 			free(id);
426 		return 0;
427 	}
428 
429 	while ((id = queue_remove(id_queue))) {
430 		if (!is_id_in_scope(SYM_CLASSES, id)) {
431 			yyerror2("class %s is not within scope", id);
432 			return -1;
433 		}
434 		cladatum = hashtab_search(policydbp->p_classes.table, id);
435 		if (!cladatum) {
436 			yyerror2("unknown class %s", id);
437 			return -1;
438 		}
439 		if (cladatum->default_range && cladatum->default_range != which) {
440 			yyerror2("conflicting default range information for class %s", id);
441 			return -1;
442 		}
443 		cladatum->default_range = which;
444 		free(id);
445 	}
446 
447 	return 0;
448 }
449 
define_common_perms(void)450 int define_common_perms(void)
451 {
452 	char *id = 0, *perm = 0;
453 	common_datum_t *comdatum = 0;
454 	perm_datum_t *perdatum = 0;
455 	int ret;
456 
457 	if (pass == 2) {
458 		while ((id = queue_remove(id_queue)))
459 			free(id);
460 		return 0;
461 	}
462 
463 	id = (char *)queue_remove(id_queue);
464 	if (!id) {
465 		yyerror("no common name for common perm definition?");
466 		return -1;
467 	}
468 	comdatum = hashtab_search(policydbp->p_commons.table, id);
469 	if (comdatum) {
470 		yyerror2("duplicate declaration for common %s\n", id);
471 		return -1;
472 	}
473 	comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
474 	if (!comdatum) {
475 		yyerror("out of memory");
476 		goto bad;
477 	}
478 	memset(comdatum, 0, sizeof(common_datum_t));
479 	ret = hashtab_insert(policydbp->p_commons.table,
480 			     (hashtab_key_t) id, (hashtab_datum_t) comdatum);
481 
482 	if (ret == SEPOL_EEXIST) {
483 		yyerror("duplicate common definition");
484 		goto bad;
485 	}
486 	if (ret == SEPOL_ENOMEM) {
487 		yyerror("hash table overflow");
488 		goto bad;
489 	}
490 	comdatum->s.value = policydbp->p_commons.nprim + 1;
491 	if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
492 		yyerror("out of memory");
493 		goto bad;
494 	}
495 	policydbp->p_commons.nprim++;
496 	while ((perm = queue_remove(id_queue))) {
497 		perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
498 		if (!perdatum) {
499 			yyerror("out of memory");
500 			goto bad_perm;
501 		}
502 		memset(perdatum, 0, sizeof(perm_datum_t));
503 		perdatum->s.value = comdatum->permissions.nprim + 1;
504 
505 		if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
506 			yyerror
507 			    ("too many permissions to fit in an access vector");
508 			goto bad_perm;
509 		}
510 		ret = hashtab_insert(comdatum->permissions.table,
511 				     (hashtab_key_t) perm,
512 				     (hashtab_datum_t) perdatum);
513 
514 		if (ret == SEPOL_EEXIST) {
515 			yyerror2("duplicate permission %s in common %s", perm,
516 				 id);
517 			goto bad_perm;
518 		}
519 		if (ret == SEPOL_ENOMEM) {
520 			yyerror("hash table overflow");
521 			goto bad_perm;
522 		}
523 		comdatum->permissions.nprim++;
524 	}
525 
526 	return 0;
527 
528       bad:
529 	if (id)
530 		free(id);
531 	if (comdatum)
532 		free(comdatum);
533 	return -1;
534 
535       bad_perm:
536 	if (perm)
537 		free(perm);
538 	if (perdatum)
539 		free(perdatum);
540 	return -1;
541 }
542 
define_av_perms(int inherits)543 int define_av_perms(int inherits)
544 {
545 	char *id;
546 	class_datum_t *cladatum;
547 	common_datum_t *comdatum;
548 	perm_datum_t *perdatum = 0, *perdatum2 = 0;
549 	int ret;
550 
551 	if (pass == 2) {
552 		while ((id = queue_remove(id_queue)))
553 			free(id);
554 		return 0;
555 	}
556 
557 	id = (char *)queue_remove(id_queue);
558 	if (!id) {
559 		yyerror("no tclass name for av perm definition?");
560 		return -1;
561 	}
562 	cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
563 						    (hashtab_key_t) id);
564 	if (!cladatum) {
565 		yyerror2("class %s is not defined", id);
566 		goto bad;
567 	}
568 	free(id);
569 
570 	if (cladatum->comdatum || cladatum->permissions.nprim) {
571 		yyerror("duplicate access vector definition");
572 		return -1;
573 	}
574 	if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
575 		yyerror("out of memory");
576 		return -1;
577 	}
578 	if (inherits) {
579 		id = (char *)queue_remove(id_queue);
580 		if (!id) {
581 			yyerror
582 			    ("no inherits name for access vector definition?");
583 			return -1;
584 		}
585 		comdatum =
586 		    (common_datum_t *) hashtab_search(policydbp->p_commons.
587 						      table,
588 						      (hashtab_key_t) id);
589 
590 		if (!comdatum) {
591 			yyerror2("common %s is not defined", id);
592 			goto bad;
593 		}
594 		cladatum->comkey = id;
595 		cladatum->comdatum = comdatum;
596 
597 		/*
598 		 * Class-specific permissions start with values
599 		 * after the last common permission.
600 		 */
601 		cladatum->permissions.nprim += comdatum->permissions.nprim;
602 	}
603 	while ((id = queue_remove(id_queue))) {
604 		perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
605 		if (!perdatum) {
606 			yyerror("out of memory");
607 			goto bad;
608 		}
609 		memset(perdatum, 0, sizeof(perm_datum_t));
610 		perdatum->s.value = ++cladatum->permissions.nprim;
611 
612 		if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
613 			yyerror
614 			    ("too many permissions to fit in an access vector");
615 			goto bad;
616 		}
617 		if (inherits) {
618 			/*
619 			 * Class-specific permissions and
620 			 * common permissions exist in the same
621 			 * name space.
622 			 */
623 			perdatum2 =
624 			    (perm_datum_t *) hashtab_search(cladatum->comdatum->
625 							    permissions.table,
626 							    (hashtab_key_t) id);
627 			if (perdatum2) {
628 				yyerror2("permission %s conflicts with an "
629 					 "inherited permission", id);
630 				goto bad;
631 			}
632 		}
633 		ret = hashtab_insert(cladatum->permissions.table,
634 				     (hashtab_key_t) id,
635 				     (hashtab_datum_t) perdatum);
636 
637 		if (ret == SEPOL_EEXIST) {
638 			yyerror2("duplicate permission %s", id);
639 			goto bad;
640 		}
641 		if (ret == SEPOL_ENOMEM) {
642 			yyerror("hash table overflow");
643 			goto bad;
644 		}
645 		if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
646 			yyerror("out of memory");
647 			goto bad;
648 		}
649 	}
650 
651 	return 0;
652 
653       bad:
654 	if (id)
655 		free(id);
656 	if (perdatum)
657 		free(perdatum);
658 	return -1;
659 }
660 
define_sens(void)661 int define_sens(void)
662 {
663 	char *id;
664 	mls_level_t *level = 0;
665 	level_datum_t *datum = 0, *aliasdatum = 0;
666 	int ret;
667 	uint32_t value;		/* dummy variable -- its value is never used */
668 
669 	if (!mlspol) {
670 		yyerror("sensitivity definition in non-MLS configuration");
671 		return -1;
672 	}
673 
674 	if (pass == 2) {
675 		while ((id = queue_remove(id_queue)))
676 			free(id);
677 		return 0;
678 	}
679 
680 	id = (char *)queue_remove(id_queue);
681 	if (!id) {
682 		yyerror("no sensitivity name for sensitivity definition?");
683 		return -1;
684 	}
685 	if (id_has_dot(id)) {
686 		yyerror("sensitivity identifiers may not contain periods");
687 		goto bad;
688 	}
689 	level = (mls_level_t *) malloc(sizeof(mls_level_t));
690 	if (!level) {
691 		yyerror("out of memory");
692 		goto bad;
693 	}
694 	mls_level_init(level);
695 	level->sens = 0;	/* actual value set in define_dominance */
696 	ebitmap_init(&level->cat);	/* actual value set in define_level */
697 
698 	datum = (level_datum_t *) malloc(sizeof(level_datum_t));
699 	if (!datum) {
700 		yyerror("out of memory");
701 		goto bad;
702 	}
703 	level_datum_init(datum);
704 	datum->isalias = FALSE;
705 	datum->level = level;
706 
707 	ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
708 	switch (ret) {
709 	case -3:{
710 			yyerror("Out of memory!");
711 			goto bad;
712 		}
713 	case -2:{
714 			yyerror("duplicate declaration of sensitivity level");
715 			goto bad;
716 		}
717 	case -1:{
718 			yyerror("could not declare sensitivity level here");
719 			goto bad;
720 		}
721 	case 0:
722 	case 1:{
723 			break;
724 		}
725 	default:{
726 			assert(0);	/* should never get here */
727 		}
728 	}
729 
730 	while ((id = queue_remove(id_queue))) {
731 		if (id_has_dot(id)) {
732 			yyerror("sensitivity aliases may not contain periods");
733 			goto bad_alias;
734 		}
735 		aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
736 		if (!aliasdatum) {
737 			yyerror("out of memory");
738 			goto bad_alias;
739 		}
740 		level_datum_init(aliasdatum);
741 		aliasdatum->isalias = TRUE;
742 		aliasdatum->level = level;
743 
744 		ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
745 		switch (ret) {
746 		case -3:{
747 				yyerror("Out of memory!");
748 				goto bad_alias;
749 			}
750 		case -2:{
751 				yyerror
752 				    ("duplicate declaration of sensitivity alias");
753 				goto bad_alias;
754 			}
755 		case -1:{
756 				yyerror
757 				    ("could not declare sensitivity alias here");
758 				goto bad_alias;
759 			}
760 		case 0:
761 		case 1:{
762 				break;
763 			}
764 		default:{
765 				assert(0);	/* should never get here */
766 			}
767 		}
768 	}
769 
770 	return 0;
771 
772       bad:
773 	if (id)
774 		free(id);
775 	if (level)
776 		free(level);
777 	if (datum) {
778 		level_datum_destroy(datum);
779 		free(datum);
780 	}
781 	return -1;
782 
783       bad_alias:
784 	if (id)
785 		free(id);
786 	if (aliasdatum) {
787 		level_datum_destroy(aliasdatum);
788 		free(aliasdatum);
789 	}
790 	return -1;
791 }
792 
define_dominance(void)793 int define_dominance(void)
794 {
795 	level_datum_t *datum;
796 	int order;
797 	char *id;
798 
799 	if (!mlspol) {
800 		yyerror("dominance definition in non-MLS configuration");
801 		return -1;
802 	}
803 
804 	if (pass == 2) {
805 		while ((id = queue_remove(id_queue)))
806 			free(id);
807 		return 0;
808 	}
809 
810 	order = 0;
811 	while ((id = (char *)queue_remove(id_queue))) {
812 		datum =
813 		    (level_datum_t *) hashtab_search(policydbp->p_levels.table,
814 						     (hashtab_key_t) id);
815 		if (!datum) {
816 			yyerror2("unknown sensitivity %s used in dominance "
817 				 "definition", id);
818 			free(id);
819 			return -1;
820 		}
821 		if (datum->level->sens != 0) {
822 			yyerror2("sensitivity %s occurs multiply in dominance "
823 				 "definition", id);
824 			free(id);
825 			return -1;
826 		}
827 		datum->level->sens = ++order;
828 
829 		/* no need to keep sensitivity name */
830 		free(id);
831 	}
832 
833 	if (order != policydbp->p_levels.nprim) {
834 		yyerror
835 		    ("all sensitivities must be specified in dominance definition");
836 		return -1;
837 	}
838 	return 0;
839 }
840 
define_category(void)841 int define_category(void)
842 {
843 	char *id;
844 	cat_datum_t *datum = 0, *aliasdatum = 0;
845 	int ret;
846 	uint32_t value;
847 
848 	if (!mlspol) {
849 		yyerror("category definition in non-MLS configuration");
850 		return -1;
851 	}
852 
853 	if (pass == 2) {
854 		while ((id = queue_remove(id_queue)))
855 			free(id);
856 		return 0;
857 	}
858 
859 	id = (char *)queue_remove(id_queue);
860 	if (!id) {
861 		yyerror("no category name for category definition?");
862 		return -1;
863 	}
864 	if (id_has_dot(id)) {
865 		yyerror("category identifiers may not contain periods");
866 		goto bad;
867 	}
868 	datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
869 	if (!datum) {
870 		yyerror("out of memory");
871 		goto bad;
872 	}
873 	cat_datum_init(datum);
874 	datum->isalias = FALSE;
875 
876 	ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
877 	switch (ret) {
878 	case -3:{
879 			yyerror("Out of memory!");
880 			goto bad;
881 		}
882 	case -2:{
883 			yyerror("duplicate declaration of category");
884 			goto bad;
885 		}
886 	case -1:{
887 			yyerror("could not declare category here");
888 			goto bad;
889 		}
890 	case 0:
891 	case 1:{
892 			break;
893 		}
894 	default:{
895 			assert(0);	/* should never get here */
896 		}
897 	}
898 	datum->s.value = value;
899 
900 	while ((id = queue_remove(id_queue))) {
901 		if (id_has_dot(id)) {
902 			yyerror("category aliases may not contain periods");
903 			goto bad_alias;
904 		}
905 		aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
906 		if (!aliasdatum) {
907 			yyerror("out of memory");
908 			goto bad_alias;
909 		}
910 		cat_datum_init(aliasdatum);
911 		aliasdatum->isalias = TRUE;
912 		aliasdatum->s.value = datum->s.value;
913 
914 		ret =
915 		    declare_symbol(SYM_CATS, id, aliasdatum, NULL,
916 				   &datum->s.value);
917 		switch (ret) {
918 		case -3:{
919 				yyerror("Out of memory!");
920 				goto bad_alias;
921 			}
922 		case -2:{
923 				yyerror
924 				    ("duplicate declaration of category aliases");
925 				goto bad_alias;
926 			}
927 		case -1:{
928 				yyerror
929 				    ("could not declare category aliases here");
930 				goto bad_alias;
931 			}
932 		case 0:
933 		case 1:{
934 				break;
935 			}
936 		default:{
937 				assert(0);	/* should never get here */
938 			}
939 		}
940 	}
941 
942 	return 0;
943 
944       bad:
945 	if (id)
946 		free(id);
947 	if (datum) {
948 		cat_datum_destroy(datum);
949 		free(datum);
950 	}
951 	return -1;
952 
953       bad_alias:
954 	if (id)
955 		free(id);
956 	if (aliasdatum) {
957 		cat_datum_destroy(aliasdatum);
958 		free(aliasdatum);
959 	}
960 	return -1;
961 }
962 
clone_level(hashtab_key_t key,hashtab_datum_t datum,void * arg)963 static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
964 {
965 	level_datum_t *levdatum = (level_datum_t *) datum;
966 	mls_level_t *level = (mls_level_t *) arg, *newlevel;
967 
968 	if (levdatum->level == level) {
969 		levdatum->defined = 1;
970 		if (!levdatum->isalias)
971 			return 0;
972 		newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
973 		if (!newlevel)
974 			return -1;
975 		if (mls_level_cpy(newlevel, level)) {
976 			free(newlevel);
977 			return -1;
978 		}
979 		levdatum->level = newlevel;
980 	}
981 	return 0;
982 }
983 
define_level(void)984 int define_level(void)
985 {
986 	char *id;
987 	level_datum_t *levdatum;
988 
989 	if (!mlspol) {
990 		yyerror("level definition in non-MLS configuration");
991 		return -1;
992 	}
993 
994 	if (pass == 2) {
995 		while ((id = queue_remove(id_queue)))
996 			free(id);
997 		return 0;
998 	}
999 
1000 	id = (char *)queue_remove(id_queue);
1001 	if (!id) {
1002 		yyerror("no level name for level definition?");
1003 		return -1;
1004 	}
1005 	levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
1006 						    (hashtab_key_t) id);
1007 	if (!levdatum) {
1008 		yyerror2("unknown sensitivity %s used in level definition", id);
1009 		free(id);
1010 		return -1;
1011 	}
1012 	if (ebitmap_length(&levdatum->level->cat)) {
1013 		yyerror2("sensitivity %s used in multiple level definitions",
1014 			 id);
1015 		free(id);
1016 		return -1;
1017 	}
1018 	free(id);
1019 
1020 	levdatum->defined = 1;
1021 
1022 	while ((id = queue_remove(id_queue))) {
1023 		cat_datum_t *cdatum;
1024 		int range_start, range_end, i;
1025 
1026 		if (id_has_dot(id)) {
1027 			char *id_start = id;
1028 			char *id_end = strchr(id, '.');
1029 
1030 			*(id_end++) = '\0';
1031 
1032 			cdatum =
1033 			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
1034 							   table,
1035 							   (hashtab_key_t)
1036 							   id_start);
1037 			if (!cdatum) {
1038 				yyerror2("unknown category %s", id_start);
1039 				free(id);
1040 				return -1;
1041 			}
1042 			range_start = cdatum->s.value - 1;
1043 			cdatum =
1044 			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
1045 							   table,
1046 							   (hashtab_key_t)
1047 							   id_end);
1048 			if (!cdatum) {
1049 				yyerror2("unknown category %s", id_end);
1050 				free(id);
1051 				return -1;
1052 			}
1053 			range_end = cdatum->s.value - 1;
1054 
1055 			if (range_end < range_start) {
1056 				yyerror2("category range is invalid");
1057 				free(id);
1058 				return -1;
1059 			}
1060 		} else {
1061 			cdatum =
1062 			    (cat_datum_t *) hashtab_search(policydbp->p_cats.
1063 							   table,
1064 							   (hashtab_key_t) id);
1065 			range_start = range_end = cdatum->s.value - 1;
1066 		}
1067 
1068 		for (i = range_start; i <= range_end; i++) {
1069 			if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
1070 				yyerror("out of memory");
1071 				free(id);
1072 				return -1;
1073 			}
1074 		}
1075 
1076 		free(id);
1077 	}
1078 
1079 	if (hashtab_map
1080 	    (policydbp->p_levels.table, clone_level, levdatum->level)) {
1081 		yyerror("out of memory");
1082 		return -1;
1083 	}
1084 
1085 	return 0;
1086 }
1087 
define_attrib(void)1088 int define_attrib(void)
1089 {
1090 	if (pass == 2) {
1091 		free(queue_remove(id_queue));
1092 		return 0;
1093 	}
1094 
1095 	if (declare_type(TRUE, TRUE) == NULL) {
1096 		return -1;
1097 	}
1098 	return 0;
1099 }
1100 
add_aliases_to_type(type_datum_t * type)1101 static int add_aliases_to_type(type_datum_t * type)
1102 {
1103 	char *id;
1104 	type_datum_t *aliasdatum = NULL;
1105 	int ret;
1106 	while ((id = queue_remove(id_queue))) {
1107 		if (id_has_dot(id)) {
1108 			free(id);
1109 			yyerror
1110 			    ("type alias identifiers may not contain periods");
1111 			return -1;
1112 		}
1113 		aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
1114 		if (!aliasdatum) {
1115 			free(id);
1116 			yyerror("Out of memory!");
1117 			return -1;
1118 		}
1119 		memset(aliasdatum, 0, sizeof(type_datum_t));
1120 		aliasdatum->s.value = type->s.value;
1121 
1122 		ret = declare_symbol(SYM_TYPES, id, aliasdatum,
1123 				     NULL, &aliasdatum->s.value);
1124 		switch (ret) {
1125 		case -3:{
1126 				yyerror("Out of memory!");
1127 				goto cleanup;
1128 			}
1129 		case -2:{
1130 				yyerror2("duplicate declaration of alias %s",
1131 					 id);
1132 				goto cleanup;
1133 			}
1134 		case -1:{
1135 				yyerror("could not declare alias here");
1136 				goto cleanup;
1137 			}
1138 		case 0:	 	break;
1139 		case 1:{
1140 				/* ret == 1 means the alias was required and therefore already
1141 				 * has a value. Set it up as an alias with a different primary. */
1142 				type_datum_destroy(aliasdatum);
1143 				free(aliasdatum);
1144 
1145 				aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
1146 				assert(aliasdatum);
1147 
1148 				aliasdatum->primary = type->s.value;
1149 				aliasdatum->flavor = TYPE_ALIAS;
1150 
1151 				break;
1152 			}
1153 		default:{
1154 				assert(0);	/* should never get here */
1155 			}
1156 		}
1157 	}
1158 	return 0;
1159       cleanup:
1160 	free(id);
1161 	type_datum_destroy(aliasdatum);
1162 	free(aliasdatum);
1163 	return -1;
1164 }
1165 
define_typealias(void)1166 int define_typealias(void)
1167 {
1168 	char *id;
1169 	type_datum_t *t;
1170 
1171 	if (pass == 2) {
1172 		while ((id = queue_remove(id_queue)))
1173 			free(id);
1174 		return 0;
1175 	}
1176 
1177 	id = (char *)queue_remove(id_queue);
1178 	if (!id) {
1179 		yyerror("no type name for typealias definition?");
1180 		return -1;
1181 	}
1182 
1183 	if (!is_id_in_scope(SYM_TYPES, id)) {
1184 		yyerror2("type %s is not within scope", id);
1185 		free(id);
1186 		return -1;
1187 	}
1188 	t = hashtab_search(policydbp->p_types.table, id);
1189 	if (!t || t->flavor == TYPE_ATTRIB) {
1190 		yyerror2("unknown type %s, or it was already declared as an "
1191 			 "attribute", id);
1192 		free(id);
1193 		return -1;
1194 	}
1195 	return add_aliases_to_type(t);
1196 }
1197 
define_typeattribute(void)1198 int define_typeattribute(void)
1199 {
1200 	char *id;
1201 	type_datum_t *t, *attr;
1202 
1203 	if (pass == 2) {
1204 		while ((id = queue_remove(id_queue)))
1205 			free(id);
1206 		return 0;
1207 	}
1208 
1209 	id = (char *)queue_remove(id_queue);
1210 	if (!id) {
1211 		yyerror("no type name for typeattribute definition?");
1212 		return -1;
1213 	}
1214 
1215 	if (!is_id_in_scope(SYM_TYPES, id)) {
1216 		yyerror2("type %s is not within scope", id);
1217 		free(id);
1218 		return -1;
1219 	}
1220 	t = hashtab_search(policydbp->p_types.table, id);
1221 	if (!t || t->flavor == TYPE_ATTRIB) {
1222 		yyerror2("unknown type %s", id);
1223 		free(id);
1224 		return -1;
1225 	}
1226 
1227 	while ((id = queue_remove(id_queue))) {
1228 		if (!is_id_in_scope(SYM_TYPES, id)) {
1229 			yyerror2("attribute %s is not within scope", id);
1230 			free(id);
1231 			return -1;
1232 		}
1233 		attr = hashtab_search(policydbp->p_types.table, id);
1234 		if (!attr) {
1235 			/* treat it as a fatal error */
1236 			yyerror2("attribute %s is not declared", id);
1237 			free(id);
1238 			return -1;
1239 		}
1240 
1241 		if (attr->flavor != TYPE_ATTRIB) {
1242 			yyerror2("%s is a type, not an attribute", id);
1243 			free(id);
1244 			return -1;
1245 		}
1246 
1247 		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1248 			yyerror("Out of memory!");
1249 			return -1;
1250 		}
1251 
1252 		if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
1253 			yyerror("out of memory");
1254 			return -1;
1255 		}
1256 	}
1257 
1258 	return 0;
1259 }
1260 
define_typebounds_helper(char * bounds_id,char * type_id)1261 static int define_typebounds_helper(char *bounds_id, char *type_id)
1262 {
1263 	type_datum_t *bounds, *type;
1264 
1265 	if (!is_id_in_scope(SYM_TYPES, bounds_id)) {
1266 		yyerror2("type %s is not within scope", bounds_id);
1267 		return -1;
1268 	}
1269 
1270 	bounds = hashtab_search(policydbp->p_types.table, bounds_id);
1271 	if (!bounds || bounds->flavor == TYPE_ATTRIB) {
1272 		yyerror2("hoge unknown type %s", bounds_id);
1273 		return -1;
1274 	}
1275 
1276 	if (!is_id_in_scope(SYM_TYPES, type_id)) {
1277 		yyerror2("type %s is not within scope", type_id);
1278 		return -1;
1279 	}
1280 
1281 	type = hashtab_search(policydbp->p_types.table, type_id);
1282 	if (!type || type->flavor == TYPE_ATTRIB) {
1283 		yyerror2("type %s is not declared", type_id);
1284 		return -1;
1285 	}
1286 
1287 	if (type->flavor == TYPE_TYPE && !type->primary) {
1288 		type = policydbp->type_val_to_struct[type->s.value - 1];
1289 	} else if (type->flavor == TYPE_ALIAS) {
1290 		type = policydbp->type_val_to_struct[type->primary - 1];
1291 	}
1292 
1293 	if (!type->bounds)
1294 		type->bounds = bounds->s.value;
1295 	else if (type->bounds != bounds->s.value) {
1296 		yyerror2("type %s has inconsistent master {%s,%s}",
1297 			 type_id,
1298 			 policydbp->p_type_val_to_name[type->bounds - 1],
1299 			 policydbp->p_type_val_to_name[bounds->s.value - 1]);
1300 		return -1;
1301 	}
1302 
1303 	return 0;
1304 }
1305 
define_typebounds(void)1306 int define_typebounds(void)
1307 {
1308 	char *bounds, *id;
1309 
1310 	if (pass == 1) {
1311 		while ((id = queue_remove(id_queue)))
1312 			free(id);
1313 		return 0;
1314 	}
1315 
1316 	bounds = (char *) queue_remove(id_queue);
1317 	if (!bounds) {
1318 		yyerror("no type name for typebounds definition?");
1319 		return -1;
1320 	}
1321 
1322 	while ((id = queue_remove(id_queue))) {
1323 		if (define_typebounds_helper(bounds, id))
1324 			return -1;
1325 		free(id);
1326 	}
1327 	free(bounds);
1328 
1329 	return 0;
1330 }
1331 
define_type(int alias)1332 int define_type(int alias)
1333 {
1334 	char *id;
1335 	type_datum_t *datum, *attr;
1336 
1337 	if (pass == 2) {
1338 		/*
1339 		 * If type name contains ".", we have to define boundary
1340 		 * relationship implicitly to keep compatibility with
1341 		 * old name based hierarchy.
1342 		 */
1343 		if ((id = queue_remove(id_queue))) {
1344 			char *bounds, *delim;
1345 
1346 			if ((delim = strrchr(id, '.'))
1347 			    && (bounds = strdup(id))) {
1348 				bounds[(size_t)(delim - id)] = '\0';
1349 
1350 				if (define_typebounds_helper(bounds, id))
1351 					return -1;
1352 				free(bounds);
1353 			}
1354 			free(id);
1355 		}
1356 
1357 		if (alias) {
1358 			while ((id = queue_remove(id_queue)))
1359 				free(id);
1360 		}
1361 
1362 		while ((id = queue_remove(id_queue)))
1363 			free(id);
1364 		return 0;
1365 	}
1366 
1367 	if ((datum = declare_type(TRUE, FALSE)) == NULL) {
1368 		return -1;
1369 	}
1370 
1371 	if (alias) {
1372 		if (add_aliases_to_type(datum) == -1) {
1373 			return -1;
1374 		}
1375 	}
1376 
1377 	while ((id = queue_remove(id_queue))) {
1378 		if (!is_id_in_scope(SYM_TYPES, id)) {
1379 			yyerror2("attribute %s is not within scope", id);
1380 			free(id);
1381 			return -1;
1382 		}
1383 		attr = hashtab_search(policydbp->p_types.table, id);
1384 		if (!attr) {
1385 			/* treat it as a fatal error */
1386 			yyerror2("attribute %s is not declared", id);
1387 			return -1;
1388 		}
1389 
1390 		if (attr->flavor != TYPE_ATTRIB) {
1391 			yyerror2("%s is a type, not an attribute", id);
1392 			return -1;
1393 		}
1394 
1395 		if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1396 			yyerror("Out of memory!");
1397 			return -1;
1398 		}
1399 
1400 		if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
1401 			yyerror("Out of memory");
1402 			return -1;
1403 		}
1404 	}
1405 
1406 	return 0;
1407 }
1408 
1409 struct val_to_name {
1410 	unsigned int val;
1411 	char *name;
1412 };
1413 
1414 /* Adds a type, given by its textual name, to a typeset.  If *add is
1415    0, then add the type to the negative set; otherwise if *add is 1
1416    then add it to the positive side. */
set_types(type_set_t * set,char * id,int * add,char starallowed)1417 static int set_types(type_set_t * set, char *id, int *add, char starallowed)
1418 {
1419 	type_datum_t *t;
1420 
1421 	if (strcmp(id, "*") == 0) {
1422 		if (!starallowed) {
1423 			yyerror("* not allowed in this type of rule");
1424 			return -1;
1425 		}
1426 		/* set TYPE_STAR flag */
1427 		set->flags = TYPE_STAR;
1428 		free(id);
1429 		*add = 1;
1430 		return 0;
1431 	}
1432 
1433 	if (strcmp(id, "~") == 0) {
1434 		if (!starallowed) {
1435 			yyerror("~ not allowed in this type of rule");
1436 			return -1;
1437 		}
1438 		/* complement the set */
1439 		set->flags = TYPE_COMP;
1440 		free(id);
1441 		*add = 1;
1442 		return 0;
1443 	}
1444 
1445 	if (strcmp(id, "-") == 0) {
1446 		*add = 0;
1447 		free(id);
1448 		return 0;
1449 	}
1450 
1451 	if (!is_id_in_scope(SYM_TYPES, id)) {
1452 		yyerror2("type %s is not within scope", id);
1453 		free(id);
1454 		return -1;
1455 	}
1456 	t = hashtab_search(policydbp->p_types.table, id);
1457 	if (!t) {
1458 		yyerror2("unknown type %s", id);
1459 		free(id);
1460 		return -1;
1461 	}
1462 
1463 	if (*add == 0) {
1464 		if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
1465 			goto oom;
1466 	} else {
1467 		if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
1468 			goto oom;
1469 	}
1470 	free(id);
1471 	*add = 1;
1472 	return 0;
1473       oom:
1474 	yyerror("Out of memory");
1475 	free(id);
1476 	return -1;
1477 }
1478 
define_compute_type_helper(int which,avrule_t ** rule)1479 int define_compute_type_helper(int which, avrule_t ** rule)
1480 {
1481 	char *id;
1482 	type_datum_t *datum;
1483 	ebitmap_t tclasses;
1484 	ebitmap_node_t *node;
1485 	avrule_t *avrule;
1486 	class_perm_node_t *perm;
1487 	int i, add = 1;
1488 
1489 	avrule = malloc(sizeof(avrule_t));
1490 	if (!avrule) {
1491 		yyerror("out of memory");
1492 		return -1;
1493 	}
1494 	avrule_init(avrule);
1495 	avrule->specified = which;
1496 	avrule->line = policydb_lineno;
1497 
1498 	while ((id = queue_remove(id_queue))) {
1499 		if (set_types(&avrule->stypes, id, &add, 0))
1500 			goto bad;
1501 	}
1502 	add = 1;
1503 	while ((id = queue_remove(id_queue))) {
1504 		if (set_types(&avrule->ttypes, id, &add, 0))
1505 			goto bad;
1506 	}
1507 
1508 	ebitmap_init(&tclasses);
1509 	if (read_classes(&tclasses))
1510 		goto bad;
1511 
1512 	id = (char *)queue_remove(id_queue);
1513 	if (!id) {
1514 		yyerror("no newtype?");
1515 		goto bad;
1516 	}
1517 	if (!is_id_in_scope(SYM_TYPES, id)) {
1518 		yyerror2("type %s is not within scope", id);
1519 		free(id);
1520 		goto bad;
1521 	}
1522 	datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1523 						(hashtab_key_t) id);
1524 	if (!datum || datum->flavor == TYPE_ATTRIB) {
1525 		yyerror2("unknown type %s", id);
1526 		goto bad;
1527 	}
1528 
1529 	ebitmap_for_each_bit(&tclasses, node, i) {
1530 		if (ebitmap_node_get_bit(node, i)) {
1531 			perm = malloc(sizeof(class_perm_node_t));
1532 			if (!perm) {
1533 				yyerror("out of memory");
1534 				goto bad;
1535 			}
1536 			class_perm_node_init(perm);
1537 			perm->class = i + 1;
1538 			perm->data = datum->s.value;
1539 			perm->next = avrule->perms;
1540 			avrule->perms = perm;
1541 		}
1542 	}
1543 	ebitmap_destroy(&tclasses);
1544 
1545 	*rule = avrule;
1546 	return 0;
1547 
1548       bad:
1549 	avrule_destroy(avrule);
1550 	free(avrule);
1551 	return -1;
1552 }
1553 
define_compute_type(int which)1554 int define_compute_type(int which)
1555 {
1556 	char *id;
1557 	avrule_t *avrule;
1558 
1559 	if (pass == 1) {
1560 		while ((id = queue_remove(id_queue)))
1561 			free(id);
1562 		while ((id = queue_remove(id_queue)))
1563 			free(id);
1564 		while ((id = queue_remove(id_queue)))
1565 			free(id);
1566 		id = queue_remove(id_queue);
1567 		free(id);
1568 		return 0;
1569 	}
1570 
1571 	if (define_compute_type_helper(which, &avrule))
1572 		return -1;
1573 
1574 	append_avrule(avrule);
1575 	return 0;
1576 }
1577 
define_cond_compute_type(int which)1578 avrule_t *define_cond_compute_type(int which)
1579 {
1580 	char *id;
1581 	avrule_t *avrule;
1582 
1583 	if (pass == 1) {
1584 		while ((id = queue_remove(id_queue)))
1585 			free(id);
1586 		while ((id = queue_remove(id_queue)))
1587 			free(id);
1588 		while ((id = queue_remove(id_queue)))
1589 			free(id);
1590 		id = queue_remove(id_queue);
1591 		free(id);
1592 		return (avrule_t *) 1;
1593 	}
1594 
1595 	if (define_compute_type_helper(which, &avrule))
1596 		return COND_ERR;
1597 
1598 	return avrule;
1599 }
1600 
define_bool_tunable(int is_tunable)1601 int define_bool_tunable(int is_tunable)
1602 {
1603 	char *id, *bool_value;
1604 	cond_bool_datum_t *datum;
1605 	int ret;
1606 	uint32_t value;
1607 
1608 	if (pass == 2) {
1609 		while ((id = queue_remove(id_queue)))
1610 			free(id);
1611 		return 0;
1612 	}
1613 
1614 	id = (char *)queue_remove(id_queue);
1615 	if (!id) {
1616 		yyerror("no identifier for bool definition?");
1617 		return -1;
1618 	}
1619 	if (id_has_dot(id)) {
1620 		free(id);
1621 		yyerror("boolean identifiers may not contain periods");
1622 		return -1;
1623 	}
1624 	datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1625 	if (!datum) {
1626 		yyerror("out of memory");
1627 		free(id);
1628 		return -1;
1629 	}
1630 	memset(datum, 0, sizeof(cond_bool_datum_t));
1631 	if (is_tunable)
1632 		datum->flags |= COND_BOOL_FLAGS_TUNABLE;
1633 	ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1634 	switch (ret) {
1635 	case -3:{
1636 			yyerror("Out of memory!");
1637 			goto cleanup;
1638 		}
1639 	case -2:{
1640 			yyerror2("duplicate declaration of boolean %s", id);
1641 			goto cleanup;
1642 		}
1643 	case -1:{
1644 			yyerror("could not declare boolean here");
1645 			goto cleanup;
1646 		}
1647 	case 0:
1648 	case 1:{
1649 			break;
1650 		}
1651 	default:{
1652 			assert(0);	/* should never get here */
1653 		}
1654 	}
1655 	datum->s.value = value;
1656 
1657 	bool_value = (char *)queue_remove(id_queue);
1658 	if (!bool_value) {
1659 		yyerror("no default value for bool definition?");
1660 		free(id);
1661 		return -1;
1662 	}
1663 
1664 	datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
1665 	return 0;
1666       cleanup:
1667 	cond_destroy_bool(id, datum, NULL);
1668 	return -1;
1669 }
1670 
define_cond_pol_list(avrule_t * avlist,avrule_t * sl)1671 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
1672 {
1673 	if (pass == 1) {
1674 		/* return something so we get through pass 1 */
1675 		return (avrule_t *) 1;
1676 	}
1677 
1678 	if (sl == NULL) {
1679 		/* This is a require block, return previous list */
1680 		return avlist;
1681 	}
1682 
1683 	/* prepend the new avlist to the pre-existing one */
1684 	sl->next = avlist;
1685 	return sl;
1686 }
1687 
define_te_avtab_helper(int which,avrule_t ** rule)1688 int define_te_avtab_helper(int which, avrule_t ** rule)
1689 {
1690 	char *id;
1691 	class_datum_t *cladatum;
1692 	perm_datum_t *perdatum = NULL;
1693 	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
1694 	ebitmap_t tclasses;
1695 	ebitmap_node_t *node;
1696 	avrule_t *avrule;
1697 	unsigned int i;
1698 	int add = 1, ret = 0;
1699 	int suppress = 0;
1700 
1701 	avrule = (avrule_t *) malloc(sizeof(avrule_t));
1702 	if (!avrule) {
1703 		yyerror("memory error");
1704 		ret = -1;
1705 		goto out;
1706 	}
1707 	avrule_init(avrule);
1708 	avrule->specified = which;
1709 	avrule->line = policydb_lineno;
1710 
1711 	while ((id = queue_remove(id_queue))) {
1712 		if (set_types
1713 		    (&avrule->stypes, id, &add,
1714 		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
1715 			ret = -1;
1716 			goto out;
1717 		}
1718 	}
1719 	add = 1;
1720 	while ((id = queue_remove(id_queue))) {
1721 		if (strcmp(id, "self") == 0) {
1722 			free(id);
1723 			avrule->flags |= RULE_SELF;
1724 			continue;
1725 		}
1726 		if (set_types
1727 		    (&avrule->ttypes, id, &add,
1728 		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
1729 			ret = -1;
1730 			goto out;
1731 		}
1732 	}
1733 
1734 	ebitmap_init(&tclasses);
1735 	ret = read_classes(&tclasses);
1736 	if (ret)
1737 		goto out;
1738 
1739 	perms = NULL;
1740 	ebitmap_for_each_bit(&tclasses, node, i) {
1741 		if (!ebitmap_node_get_bit(node, i))
1742 			continue;
1743 		cur_perms =
1744 		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
1745 		if (!cur_perms) {
1746 			yyerror("out of memory");
1747 			ret = -1;
1748 			goto out;
1749 		}
1750 		class_perm_node_init(cur_perms);
1751 		cur_perms->class = i + 1;
1752 		if (!perms)
1753 			perms = cur_perms;
1754 		if (tail)
1755 			tail->next = cur_perms;
1756 		tail = cur_perms;
1757 	}
1758 
1759 	while ((id = queue_remove(id_queue))) {
1760 		cur_perms = perms;
1761 		ebitmap_for_each_bit(&tclasses, node, i) {
1762 			if (!ebitmap_node_get_bit(node, i))
1763 				continue;
1764 			cladatum = policydbp->class_val_to_struct[i];
1765 
1766 			if (strcmp(id, "*") == 0) {
1767 				/* set all permissions in the class */
1768 				cur_perms->data = ~0U;
1769 				goto next;
1770 			}
1771 
1772 			if (strcmp(id, "~") == 0) {
1773 				/* complement the set */
1774 				if (which == AVRULE_DONTAUDIT)
1775 					yywarn("dontaudit rule with a ~?");
1776 				cur_perms->data = ~cur_perms->data;
1777 				goto next;
1778 			}
1779 
1780 			perdatum =
1781 			    hashtab_search(cladatum->permissions.table, id);
1782 			if (!perdatum) {
1783 				if (cladatum->comdatum) {
1784 					perdatum =
1785 					    hashtab_search(cladatum->comdatum->
1786 							   permissions.table,
1787 							   id);
1788 				}
1789 			}
1790 			if (!perdatum) {
1791 				if (!suppress)
1792 					yyerror2("permission %s is not defined"
1793 					     " for class %s", id,
1794 					     policydbp->p_class_val_to_name[i]);
1795 				continue;
1796 			} else
1797 			    if (!is_perm_in_scope
1798 				(id, policydbp->p_class_val_to_name[i])) {
1799 				if (!suppress) {
1800 					yyerror2("permission %s of class %s is"
1801 					     " not within scope", id,
1802 					     policydbp->p_class_val_to_name[i]);
1803 				}
1804 				continue;
1805 			} else {
1806 				cur_perms->data |= 1U << (perdatum->s.value - 1);
1807 			}
1808 		      next:
1809 			cur_perms = cur_perms->next;
1810 		}
1811 
1812 		free(id);
1813 	}
1814 
1815 	ebitmap_destroy(&tclasses);
1816 
1817 	avrule->perms = perms;
1818 	*rule = avrule;
1819 
1820       out:
1821 	return ret;
1822 
1823 }
1824 
define_cond_te_avtab(int which)1825 avrule_t *define_cond_te_avtab(int which)
1826 {
1827 	char *id;
1828 	avrule_t *avrule;
1829 	int i;
1830 
1831 	if (pass == 1) {
1832 		for (i = 0; i < 4; i++) {
1833 			while ((id = queue_remove(id_queue)))
1834 				free(id);
1835 		}
1836 		return (avrule_t *) 1;	/* any non-NULL value */
1837 	}
1838 
1839 	if (define_te_avtab_helper(which, &avrule))
1840 		return COND_ERR;
1841 
1842 	return avrule;
1843 }
1844 
define_te_avtab(int which)1845 int define_te_avtab(int which)
1846 {
1847 	char *id;
1848 	avrule_t *avrule;
1849 	int i;
1850 
1851 	if (pass == 1) {
1852 		for (i = 0; i < 4; i++) {
1853 			while ((id = queue_remove(id_queue)))
1854 				free(id);
1855 		}
1856 		return 0;
1857 	}
1858 
1859 	if (define_te_avtab_helper(which, &avrule))
1860 		return -1;
1861 
1862 	/* append this avrule to the end of the current rules list */
1863 	append_avrule(avrule);
1864 	return 0;
1865 }
1866 
1867 /* The role-types rule is no longer used to declare regular role or
1868  * role attribute, but solely aimed for declaring role-types associations.
1869  */
define_role_types(void)1870 int define_role_types(void)
1871 {
1872 	role_datum_t *role;
1873 	char *id;
1874 	int add = 1;
1875 
1876 	if (pass == 1) {
1877 		while ((id = queue_remove(id_queue)))
1878 			free(id);
1879 		return 0;
1880 	}
1881 
1882 	id = (char *)queue_remove(id_queue);
1883 	if (!id) {
1884 		yyerror("no role name for role-types rule?");
1885 		return -1;
1886 	}
1887 
1888 	if (!is_id_in_scope(SYM_ROLES, id)) {
1889 		yyerror2("role %s is not within scope", id);
1890 		free(id);
1891 		return -1;
1892 	}
1893 
1894 	role = hashtab_search(policydbp->p_roles.table, id);
1895 	if (!role) {
1896 		yyerror2("unknown role %s", id);
1897 		free(id);
1898 		return -1;
1899 	}
1900 
1901 	while ((id = queue_remove(id_queue))) {
1902 		if (set_types(&role->types, id, &add, 0))
1903 			return -1;
1904 	}
1905 
1906 	return 0;
1907 }
1908 
define_attrib_role(void)1909 int define_attrib_role(void)
1910 {
1911 	if (pass == 2) {
1912 		free(queue_remove(id_queue));
1913 		return 0;
1914 	}
1915 
1916 	/* Declare a role attribute */
1917 	if (declare_role(TRUE) == NULL)
1918 		return -1;
1919 
1920 	return 0;
1921 }
1922 
define_role_attr(void)1923 int define_role_attr(void)
1924 {
1925 	char *id;
1926 	role_datum_t *r, *attr;
1927 
1928 	if (pass == 2) {
1929 		while ((id = queue_remove(id_queue)))
1930 			free(id);
1931 		return 0;
1932 	}
1933 
1934 	/* Declare a regular role */
1935 	if ((r = declare_role(FALSE)) == NULL)
1936 		return -1;
1937 
1938 	while ((id = queue_remove(id_queue))) {
1939 		if (!is_id_in_scope(SYM_ROLES, id)) {
1940 			yyerror2("attribute %s is not within scope", id);
1941 			free(id);
1942 			return -1;
1943 		}
1944 		attr = hashtab_search(policydbp->p_roles.table, id);
1945 		if (!attr) {
1946 			/* treat it as a fatal error */
1947 			yyerror2("role attribute %s is not declared", id);
1948 			free(id);
1949 			return -1;
1950 		}
1951 
1952 		if (attr->flavor != ROLE_ATTRIB) {
1953 			yyerror2("%s is a regular role, not an attribute", id);
1954 			free(id);
1955 			return -1;
1956 		}
1957 
1958 		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
1959 			yyerror("Out of memory!");
1960 			return -1;
1961 		}
1962 
1963 		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
1964 			yyerror("out of memory");
1965 			return -1;
1966 		}
1967 	}
1968 
1969 	return 0;
1970 }
1971 
define_roleattribute(void)1972 int define_roleattribute(void)
1973 {
1974 	char *id;
1975 	role_datum_t *r, *attr;
1976 
1977 	if (pass == 2) {
1978 		while ((id = queue_remove(id_queue)))
1979 			free(id);
1980 		return 0;
1981 	}
1982 
1983 	id = (char *)queue_remove(id_queue);
1984 	if (!id) {
1985 		yyerror("no role name for roleattribute definition?");
1986 		return -1;
1987 	}
1988 
1989 	if (!is_id_in_scope(SYM_ROLES, id)) {
1990 		yyerror2("role %s is not within scope", id);
1991 		free(id);
1992 		return -1;
1993 	}
1994 	r = hashtab_search(policydbp->p_roles.table, id);
1995 	/* We support adding one role attribute into another */
1996 	if (!r) {
1997 		yyerror2("unknown role %s", id);
1998 		free(id);
1999 		return -1;
2000 	}
2001 
2002 	while ((id = queue_remove(id_queue))) {
2003 		if (!is_id_in_scope(SYM_ROLES, id)) {
2004 			yyerror2("attribute %s is not within scope", id);
2005 			free(id);
2006 			return -1;
2007 		}
2008 		attr = hashtab_search(policydbp->p_roles.table, id);
2009 		if (!attr) {
2010 			/* treat it as a fatal error */
2011 			yyerror2("role attribute %s is not declared", id);
2012 			free(id);
2013 			return -1;
2014 		}
2015 
2016 		if (attr->flavor != ROLE_ATTRIB) {
2017 			yyerror2("%s is a regular role, not an attribute", id);
2018 			free(id);
2019 			return -1;
2020 		}
2021 
2022 		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2023 			yyerror("Out of memory!");
2024 			return -1;
2025 		}
2026 
2027 		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2028 			yyerror("out of memory");
2029 			return -1;
2030 		}
2031 	}
2032 
2033 	return 0;
2034 }
2035 
merge_roles_dom(role_datum_t * r1,role_datum_t * r2)2036 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
2037 {
2038 	role_datum_t *new;
2039 
2040 	if (pass == 1) {
2041 		return (role_datum_t *) 1;	/* any non-NULL value */
2042 	}
2043 
2044 	new = malloc(sizeof(role_datum_t));
2045 	if (!new) {
2046 		yyerror("out of memory");
2047 		return NULL;
2048 	}
2049 	memset(new, 0, sizeof(role_datum_t));
2050 	new->s.value = 0;		/* temporary role */
2051 	if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
2052 		yyerror("out of memory");
2053 		free(new);
2054 		return NULL;
2055 	}
2056 	if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
2057 		yyerror("out of memory");
2058 		free(new);
2059 		return NULL;
2060 	}
2061 	if (!r1->s.value) {
2062 		/* free intermediate result */
2063 		type_set_destroy(&r1->types);
2064 		ebitmap_destroy(&r1->dominates);
2065 		free(r1);
2066 	}
2067 	if (!r2->s.value) {
2068 		/* free intermediate result */
2069 		yyerror("right hand role is temporary?");
2070 		type_set_destroy(&r2->types);
2071 		ebitmap_destroy(&r2->dominates);
2072 		free(r2);
2073 	}
2074 	return new;
2075 }
2076 
2077 /* This function eliminates the ordering dependency of role dominance rule */
dominate_role_recheck(hashtab_key_t key,hashtab_datum_t datum,void * arg)2078 static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
2079 				 void *arg)
2080 {
2081 	role_datum_t *rdp = (role_datum_t *) arg;
2082 	role_datum_t *rdatum = (role_datum_t *) datum;
2083 	ebitmap_node_t *node;
2084 	int i;
2085 
2086 	/* Don't bother to process against self role */
2087 	if (rdatum->s.value == rdp->s.value)
2088 		return 0;
2089 
2090 	/* If a dominating role found */
2091 	if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
2092 		ebitmap_t types;
2093 		ebitmap_init(&types);
2094 		if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
2095 			ebitmap_destroy(&types);
2096 			return -1;
2097 		}
2098 		/* raise types and dominates from dominated role */
2099 		ebitmap_for_each_bit(&rdp->dominates, node, i) {
2100 			if (ebitmap_node_get_bit(node, i))
2101 				if (ebitmap_set_bit
2102 				    (&rdatum->dominates, i, TRUE))
2103 					goto oom;
2104 		}
2105 		ebitmap_for_each_bit(&types, node, i) {
2106 			if (ebitmap_node_get_bit(node, i))
2107 				if (ebitmap_set_bit
2108 				    (&rdatum->types.types, i, TRUE))
2109 					goto oom;
2110 		}
2111 		ebitmap_destroy(&types);
2112 	}
2113 
2114 	/* go through all the roles */
2115 	return 0;
2116       oom:
2117 	yyerror("Out of memory");
2118 	return -1;
2119 }
2120 
define_role_dom(role_datum_t * r)2121 role_datum_t *define_role_dom(role_datum_t * r)
2122 {
2123 	role_datum_t *role;
2124 	char *role_id;
2125 	ebitmap_node_t *node;
2126 	unsigned int i;
2127 	int ret;
2128 
2129 	if (pass == 1) {
2130 		role_id = queue_remove(id_queue);
2131 		free(role_id);
2132 		return (role_datum_t *) 1;	/* any non-NULL value */
2133 	}
2134 
2135 	yywarn("Role dominance has been deprecated");
2136 
2137 	role_id = queue_remove(id_queue);
2138 	if (!is_id_in_scope(SYM_ROLES, role_id)) {
2139 		yyerror2("role %s is not within scope", role_id);
2140 		free(role_id);
2141 		return NULL;
2142 	}
2143 	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2144 					       role_id);
2145 	if (!role) {
2146 		role = (role_datum_t *) malloc(sizeof(role_datum_t));
2147 		if (!role) {
2148 			yyerror("out of memory");
2149 			free(role_id);
2150 			return NULL;
2151 		}
2152 		memset(role, 0, sizeof(role_datum_t));
2153 		ret =
2154 		    declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
2155 				   (hashtab_datum_t) role, &role->s.value,
2156 				   &role->s.value);
2157 		switch (ret) {
2158 		case -3:{
2159 				yyerror("Out of memory!");
2160 				goto cleanup;
2161 			}
2162 		case -2:{
2163 				yyerror2("duplicate declaration of role %s",
2164 					 role_id);
2165 				goto cleanup;
2166 			}
2167 		case -1:{
2168 				yyerror("could not declare role here");
2169 				goto cleanup;
2170 			}
2171 		case 0:
2172 		case 1:{
2173 				break;
2174 			}
2175 		default:{
2176 				assert(0);	/* should never get here */
2177 			}
2178 		}
2179 		if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
2180 			yyerror("Out of memory!");
2181 			goto cleanup;
2182 		}
2183 	}
2184 	if (r) {
2185 		ebitmap_t types;
2186 		ebitmap_init(&types);
2187 		ebitmap_for_each_bit(&r->dominates, node, i) {
2188 			if (ebitmap_node_get_bit(node, i))
2189 				if (ebitmap_set_bit(&role->dominates, i, TRUE))
2190 					goto oom;
2191 		}
2192 		if (type_set_expand(&r->types, &types, policydbp, 1)) {
2193 			ebitmap_destroy(&types);
2194 			return NULL;
2195 		}
2196 		ebitmap_for_each_bit(&types, node, i) {
2197 			if (ebitmap_node_get_bit(node, i))
2198 				if (ebitmap_set_bit
2199 				    (&role->types.types, i, TRUE))
2200 					goto oom;
2201 		}
2202 		ebitmap_destroy(&types);
2203 		if (!r->s.value) {
2204 			/* free intermediate result */
2205 			type_set_destroy(&r->types);
2206 			ebitmap_destroy(&r->dominates);
2207 			free(r);
2208 		}
2209 		/*
2210 		 * Now go through all the roles and escalate this role's
2211 		 * dominates and types if a role dominates this role.
2212 		 */
2213 		hashtab_map(policydbp->p_roles.table,
2214 			    dominate_role_recheck, role);
2215 	}
2216 	return role;
2217       cleanup:
2218 	free(role_id);
2219 	role_datum_destroy(role);
2220 	free(role);
2221 	return NULL;
2222       oom:
2223 	yyerror("Out of memory");
2224 	goto cleanup;
2225 }
2226 
role_val_to_name_helper(hashtab_key_t key,hashtab_datum_t datum,void * p)2227 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
2228 				   void *p)
2229 {
2230 	struct val_to_name *v = p;
2231 	role_datum_t *roldatum;
2232 
2233 	roldatum = (role_datum_t *) datum;
2234 
2235 	if (v->val == roldatum->s.value) {
2236 		v->name = key;
2237 		return 1;
2238 	}
2239 
2240 	return 0;
2241 }
2242 
role_val_to_name(unsigned int val)2243 static char *role_val_to_name(unsigned int val)
2244 {
2245 	struct val_to_name v;
2246 	int rc;
2247 
2248 	v.val = val;
2249 	rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2250 	if (rc)
2251 		return v.name;
2252 	return NULL;
2253 }
2254 
set_roles(role_set_t * set,char * id)2255 static int set_roles(role_set_t * set, char *id)
2256 {
2257 	role_datum_t *r;
2258 
2259 	if (strcmp(id, "*") == 0) {
2260 		free(id);
2261 		yyerror("* is not allowed for role sets");
2262 		return -1;
2263 	}
2264 
2265 	if (strcmp(id, "~") == 0) {
2266 		free(id);
2267 		yyerror("~ is not allowed for role sets");
2268 		return -1;
2269 	}
2270 	if (!is_id_in_scope(SYM_ROLES, id)) {
2271 		yyerror2("role %s is not within scope", id);
2272 		free(id);
2273 		return -1;
2274 	}
2275 	r = hashtab_search(policydbp->p_roles.table, id);
2276 	if (!r) {
2277 		yyerror2("unknown role %s", id);
2278 		free(id);
2279 		return -1;
2280 	}
2281 
2282 	if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
2283 		yyerror("out of memory");
2284 		free(id);
2285 		return -1;
2286 	}
2287 	free(id);
2288 	return 0;
2289 }
2290 
define_role_trans(int class_specified)2291 int define_role_trans(int class_specified)
2292 {
2293 	char *id;
2294 	role_datum_t *role;
2295 	role_set_t roles;
2296 	type_set_t types;
2297 	class_datum_t *cladatum;
2298 	ebitmap_t e_types, e_roles, e_classes;
2299 	ebitmap_node_t *tnode, *rnode, *cnode;
2300 	struct role_trans *tr = NULL;
2301 	struct role_trans_rule *rule = NULL;
2302 	unsigned int i, j, k;
2303 	int add = 1;
2304 
2305 	if (pass == 1) {
2306 		while ((id = queue_remove(id_queue)))
2307 			free(id);
2308 		while ((id = queue_remove(id_queue)))
2309 			free(id);
2310 		if (class_specified)
2311 			while ((id = queue_remove(id_queue)))
2312 				free(id);
2313 		id = queue_remove(id_queue);
2314 		free(id);
2315 		return 0;
2316 	}
2317 
2318 	role_set_init(&roles);
2319 	ebitmap_init(&e_roles);
2320 	type_set_init(&types);
2321 	ebitmap_init(&e_types);
2322 	ebitmap_init(&e_classes);
2323 
2324 	while ((id = queue_remove(id_queue))) {
2325 		if (set_roles(&roles, id))
2326 			return -1;
2327 	}
2328 	add = 1;
2329 	while ((id = queue_remove(id_queue))) {
2330 		if (set_types(&types, id, &add, 0))
2331 			return -1;
2332 	}
2333 
2334 	if (class_specified) {
2335 		if (read_classes(&e_classes))
2336 			return -1;
2337 	} else {
2338 		cladatum = hashtab_search(policydbp->p_classes.table,
2339 					  "process");
2340 		if (!cladatum) {
2341 			yyerror2("could not find process class for "
2342 				 "legacy role_transition statement");
2343 			return -1;
2344 		}
2345 
2346 		if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) {
2347 			yyerror("out of memory");
2348 			return -1;
2349 		}
2350 	}
2351 
2352 	id = (char *)queue_remove(id_queue);
2353 	if (!id) {
2354 		yyerror("no new role in transition definition?");
2355 		goto bad;
2356 	}
2357 	if (!is_id_in_scope(SYM_ROLES, id)) {
2358 		yyerror2("role %s is not within scope", id);
2359 		free(id);
2360 		goto bad;
2361 	}
2362 	role = hashtab_search(policydbp->p_roles.table, id);
2363 	if (!role) {
2364 		yyerror2("unknown role %s used in transition definition", id);
2365 		goto bad;
2366 	}
2367 
2368 	if (role->flavor != ROLE_ROLE) {
2369 		yyerror2("the new role %s must be a regular role", id);
2370 		goto bad;
2371 	}
2372 
2373 	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
2374 	if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
2375 		goto bad;
2376 
2377 	if (type_set_expand(&types, &e_types, policydbp, 1))
2378 		goto bad;
2379 
2380 	ebitmap_for_each_bit(&e_roles, rnode, i) {
2381 		if (!ebitmap_node_get_bit(rnode, i))
2382 			continue;
2383 		ebitmap_for_each_bit(&e_types, tnode, j) {
2384 			if (!ebitmap_node_get_bit(tnode, j))
2385 				continue;
2386 			ebitmap_for_each_bit(&e_classes, cnode, k) {
2387 				if (!ebitmap_node_get_bit(cnode, k))
2388 					continue;
2389 				for (tr = policydbp->role_tr; tr;
2390 				     tr = tr->next) {
2391 					if (tr->role == (i + 1) &&
2392 					    tr->type == (j + 1) &&
2393 					    tr->tclass == (k + 1)) {
2394 						yyerror2("duplicate role "
2395 							 "transition for "
2396 							 "(%s,%s,%s)",
2397 							 role_val_to_name(i+1),
2398 							 policydbp->p_type_val_to_name[j],
2399 							 policydbp->p_class_val_to_name[k]);
2400 						goto bad;
2401 					}
2402 				}
2403 
2404 				tr = malloc(sizeof(struct role_trans));
2405 				if (!tr) {
2406 					yyerror("out of memory");
2407 					return -1;
2408 				}
2409 				memset(tr, 0, sizeof(struct role_trans));
2410 				tr->role = i + 1;
2411 				tr->type = j + 1;
2412 				tr->tclass = k + 1;
2413 				tr->new_role = role->s.value;
2414 				tr->next = policydbp->role_tr;
2415 				policydbp->role_tr = tr;
2416 			}
2417 		}
2418 	}
2419 	/* Now add the real rule */
2420 	rule = malloc(sizeof(struct role_trans_rule));
2421 	if (!rule) {
2422 		yyerror("out of memory");
2423 		return -1;
2424 	}
2425 	memset(rule, 0, sizeof(struct role_trans_rule));
2426 	rule->roles = roles;
2427 	rule->types = types;
2428 	rule->classes = e_classes;
2429 	rule->new_role = role->s.value;
2430 
2431 	append_role_trans(rule);
2432 
2433 	ebitmap_destroy(&e_roles);
2434 	ebitmap_destroy(&e_types);
2435 
2436 	return 0;
2437 
2438       bad:
2439 	return -1;
2440 }
2441 
define_role_allow(void)2442 int define_role_allow(void)
2443 {
2444 	char *id;
2445 	struct role_allow_rule *ra = 0;
2446 
2447 	if (pass == 1) {
2448 		while ((id = queue_remove(id_queue)))
2449 			free(id);
2450 		while ((id = queue_remove(id_queue)))
2451 			free(id);
2452 		return 0;
2453 	}
2454 
2455 	ra = malloc(sizeof(role_allow_rule_t));
2456 	if (!ra) {
2457 		yyerror("out of memory");
2458 		return -1;
2459 	}
2460 	role_allow_rule_init(ra);
2461 
2462 	while ((id = queue_remove(id_queue))) {
2463 		if (set_roles(&ra->roles, id)) {
2464 			free(ra);
2465 			return -1;
2466 		}
2467 	}
2468 
2469 	while ((id = queue_remove(id_queue))) {
2470 		if (set_roles(&ra->new_roles, id)) {
2471 			free(ra);
2472 			return -1;
2473 		}
2474 	}
2475 
2476 	append_role_allow(ra);
2477 	return 0;
2478 }
2479 
define_cond_filename_trans(void)2480 avrule_t *define_cond_filename_trans(void)
2481 {
2482 	yyerror("type transitions with a filename not allowed inside "
2483 		"conditionals\n");
2484 	return COND_ERR;
2485 }
2486 
define_filename_trans(void)2487 int define_filename_trans(void)
2488 {
2489 	char *id, *name = NULL;
2490 	type_set_t stypes, ttypes;
2491 	ebitmap_t e_stypes, e_ttypes;
2492 	ebitmap_t e_tclasses;
2493 	ebitmap_node_t *snode, *tnode, *cnode;
2494 	filename_trans_t *ft;
2495 	filename_trans_rule_t *ftr;
2496 	type_datum_t *typdatum;
2497 	uint32_t otype;
2498 	unsigned int c, s, t;
2499 	int add;
2500 
2501 	if (pass == 1) {
2502 		/* stype */
2503 		while ((id = queue_remove(id_queue)))
2504 			free(id);
2505 		/* ttype */
2506 		while ((id = queue_remove(id_queue)))
2507 			free(id);
2508 		/* tclass */
2509 		while ((id = queue_remove(id_queue)))
2510 			free(id);
2511 		/* otype */
2512 		id = queue_remove(id_queue);
2513 		free(id);
2514 		/* name */
2515 		id = queue_remove(id_queue);
2516 		free(id);
2517 		return 0;
2518 	}
2519 
2520 
2521 	add = 1;
2522 	type_set_init(&stypes);
2523 	while ((id = queue_remove(id_queue))) {
2524 		if (set_types(&stypes, id, &add, 0))
2525 			goto bad;
2526 	}
2527 
2528 	add =1;
2529 	type_set_init(&ttypes);
2530 	while ((id = queue_remove(id_queue))) {
2531 		if (set_types(&ttypes, id, &add, 0))
2532 			goto bad;
2533 	}
2534 
2535 	ebitmap_init(&e_tclasses);
2536 	if (read_classes(&e_tclasses))
2537 		goto bad;
2538 
2539 	id = (char *)queue_remove(id_queue);
2540 	if (!id) {
2541 		yyerror("no otype in transition definition?");
2542 		goto bad;
2543 	}
2544 	if (!is_id_in_scope(SYM_TYPES, id)) {
2545 		yyerror2("type %s is not within scope", id);
2546 		free(id);
2547 		goto bad;
2548 	}
2549 	typdatum = hashtab_search(policydbp->p_types.table, id);
2550 	if (!typdatum) {
2551 		yyerror2("unknown type %s used in transition definition", id);
2552 		goto bad;
2553 	}
2554 	free(id);
2555 	otype = typdatum->s.value;
2556 
2557 	name = queue_remove(id_queue);
2558 	if (!name) {
2559 		yyerror("no pathname specified in filename_trans definition?");
2560 		goto bad;
2561 	}
2562 
2563 	/* We expand the class set into seperate rules.  We expand the types
2564 	 * just to make sure there are not duplicates.  They will get turned
2565 	 * into seperate rules later */
2566 	ebitmap_init(&e_stypes);
2567 	if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
2568 		goto bad;
2569 
2570 	ebitmap_init(&e_ttypes);
2571 	if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
2572 		goto bad;
2573 
2574 	ebitmap_for_each_bit(&e_tclasses, cnode, c) {
2575 		if (!ebitmap_node_get_bit(cnode, c))
2576 			continue;
2577 		ebitmap_for_each_bit(&e_stypes, snode, s) {
2578 			if (!ebitmap_node_get_bit(snode, s))
2579 				continue;
2580 			ebitmap_for_each_bit(&e_ttypes, tnode, t) {
2581 				if (!ebitmap_node_get_bit(tnode, t))
2582 					continue;
2583 
2584 				for (ft = policydbp->filename_trans; ft; ft = ft->next) {
2585 					if (ft->stype == (s + 1) &&
2586 					    ft->ttype == (t + 1) &&
2587 					    ft->tclass == (c + 1) &&
2588 					    !strcmp(ft->name, name)) {
2589 						yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
2590 							 name,
2591 							 policydbp->p_type_val_to_name[s],
2592 							 policydbp->p_type_val_to_name[t],
2593 							 policydbp->p_class_val_to_name[c]);
2594 						goto bad;
2595 					}
2596 				}
2597 
2598 				ft = malloc(sizeof(*ft));
2599 				if (!ft) {
2600 					yyerror("out of memory");
2601 					goto bad;
2602 				}
2603 				memset(ft, 0, sizeof(*ft));
2604 
2605 				ft->next = policydbp->filename_trans;
2606 				policydbp->filename_trans = ft;
2607 
2608 				ft->name = strdup(name);
2609 				if (!ft->name) {
2610 					yyerror("out of memory");
2611 					goto bad;
2612 				}
2613 				ft->stype = s + 1;
2614 				ft->ttype = t + 1;
2615 				ft->tclass = c + 1;
2616 				ft->otype = otype;
2617 			}
2618 		}
2619 
2620 		/* Now add the real rule since we didn't find any duplicates */
2621 		ftr = malloc(sizeof(*ftr));
2622 		if (!ftr) {
2623 			yyerror("out of memory");
2624 			goto bad;
2625 		}
2626 		filename_trans_rule_init(ftr);
2627 		append_filename_trans(ftr);
2628 
2629 		ftr->name = strdup(name);
2630 		ftr->stypes = stypes;
2631 		ftr->ttypes = ttypes;
2632 		ftr->tclass = c + 1;
2633 		ftr->otype = otype;
2634 	}
2635 
2636 	free(name);
2637 	ebitmap_destroy(&e_stypes);
2638 	ebitmap_destroy(&e_ttypes);
2639 	ebitmap_destroy(&e_tclasses);
2640 
2641 	return 0;
2642 
2643 bad:
2644 	free(name);
2645 	return -1;
2646 }
2647 
constraint_expr_clone(constraint_expr_t * expr)2648 static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
2649 {
2650 	constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
2651 	for (e = expr; e; e = e->next) {
2652 		newe = malloc(sizeof(*newe));
2653 		if (!newe)
2654 			goto oom;
2655 		if (constraint_expr_init(newe) == -1) {
2656 			free(newe);
2657 			goto oom;
2658 		}
2659 		if (l)
2660 			l->next = newe;
2661 		else
2662 			h = newe;
2663 		l = newe;
2664 		newe->expr_type = e->expr_type;
2665 		newe->attr = e->attr;
2666 		newe->op = e->op;
2667 		if (newe->expr_type == CEXPR_NAMES) {
2668 			if (newe->attr & CEXPR_TYPE) {
2669 				if (type_set_cpy
2670 				    (newe->type_names, e->type_names))
2671 					goto oom;
2672 			} else {
2673 				if (ebitmap_cpy(&newe->names, &e->names))
2674 					goto oom;
2675 			}
2676 		}
2677 	}
2678 
2679 	return h;
2680       oom:
2681 	e = h;
2682 	while (e) {
2683 		l = e;
2684 		e = e->next;
2685 		constraint_expr_destroy(l);
2686 	}
2687 	return NULL;
2688 }
2689 
define_constraint(constraint_expr_t * expr)2690 int define_constraint(constraint_expr_t * expr)
2691 {
2692 	struct constraint_node *node;
2693 	char *id;
2694 	class_datum_t *cladatum;
2695 	perm_datum_t *perdatum;
2696 	ebitmap_t classmap;
2697 	ebitmap_node_t *enode;
2698 	constraint_expr_t *e;
2699 	unsigned int i;
2700 	int depth;
2701 	unsigned char useexpr = 1;
2702 
2703 	if (pass == 1) {
2704 		while ((id = queue_remove(id_queue)))
2705 			free(id);
2706 		while ((id = queue_remove(id_queue)))
2707 			free(id);
2708 		return 0;
2709 	}
2710 
2711 	depth = -1;
2712 	for (e = expr; e; e = e->next) {
2713 		switch (e->expr_type) {
2714 		case CEXPR_NOT:
2715 			if (depth < 0) {
2716 				yyerror("illegal constraint expression");
2717 				return -1;
2718 			}
2719 			break;
2720 		case CEXPR_AND:
2721 		case CEXPR_OR:
2722 			if (depth < 1) {
2723 				yyerror("illegal constraint expression");
2724 				return -1;
2725 			}
2726 			depth--;
2727 			break;
2728 		case CEXPR_ATTR:
2729 		case CEXPR_NAMES:
2730 			if (e->attr & CEXPR_XTARGET) {
2731 				yyerror("illegal constraint expression");
2732 				return -1;	/* only for validatetrans rules */
2733 			}
2734 			if (depth == (CEXPR_MAXDEPTH - 1)) {
2735 				yyerror("constraint expression is too deep");
2736 				return -1;
2737 			}
2738 			depth++;
2739 			break;
2740 		default:
2741 			yyerror("illegal constraint expression");
2742 			return -1;
2743 		}
2744 	}
2745 	if (depth != 0) {
2746 		yyerror("illegal constraint expression");
2747 		return -1;
2748 	}
2749 
2750 	ebitmap_init(&classmap);
2751 	while ((id = queue_remove(id_queue))) {
2752 		if (!is_id_in_scope(SYM_CLASSES, id)) {
2753 			yyerror2("class %s is not within scope", id);
2754 			free(id);
2755 			return -1;
2756 		}
2757 		cladatum =
2758 		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2759 						     (hashtab_key_t) id);
2760 		if (!cladatum) {
2761 			yyerror2("class %s is not defined", id);
2762 			ebitmap_destroy(&classmap);
2763 			free(id);
2764 			return -1;
2765 		}
2766 		if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
2767 			yyerror("out of memory");
2768 			ebitmap_destroy(&classmap);
2769 			free(id);
2770 			return -1;
2771 		}
2772 		node = malloc(sizeof(struct constraint_node));
2773 		if (!node) {
2774 			yyerror("out of memory");
2775 			return -1;
2776 		}
2777 		memset(node, 0, sizeof(constraint_node_t));
2778 		if (useexpr) {
2779 			node->expr = expr;
2780 			useexpr = 0;
2781 		} else {
2782 			node->expr = constraint_expr_clone(expr);
2783 		}
2784 		if (!node->expr) {
2785 			yyerror("out of memory");
2786 			free(node);
2787 			return -1;
2788 		}
2789 		node->permissions = 0;
2790 
2791 		node->next = cladatum->constraints;
2792 		cladatum->constraints = node;
2793 
2794 		free(id);
2795 	}
2796 
2797 	while ((id = queue_remove(id_queue))) {
2798 		ebitmap_for_each_bit(&classmap, enode, i) {
2799 			if (ebitmap_node_get_bit(enode, i)) {
2800 				cladatum = policydbp->class_val_to_struct[i];
2801 				node = cladatum->constraints;
2802 
2803 				perdatum =
2804 				    (perm_datum_t *) hashtab_search(cladatum->
2805 								    permissions.
2806 								    table,
2807 								    (hashtab_key_t)
2808 								    id);
2809 				if (!perdatum) {
2810 					if (cladatum->comdatum) {
2811 						perdatum =
2812 						    (perm_datum_t *)
2813 						    hashtab_search(cladatum->
2814 								   comdatum->
2815 								   permissions.
2816 								   table,
2817 								   (hashtab_key_t)
2818 								   id);
2819 					}
2820 					if (!perdatum) {
2821 						yyerror2("permission %s is not"
2822 							 " defined", id);
2823 						free(id);
2824 						ebitmap_destroy(&classmap);
2825 						return -1;
2826 					}
2827 				}
2828 				node->permissions |=
2829 				    (1 << (perdatum->s.value - 1));
2830 			}
2831 		}
2832 		free(id);
2833 	}
2834 
2835 	ebitmap_destroy(&classmap);
2836 
2837 	return 0;
2838 }
2839 
define_validatetrans(constraint_expr_t * expr)2840 int define_validatetrans(constraint_expr_t * expr)
2841 {
2842 	struct constraint_node *node;
2843 	char *id;
2844 	class_datum_t *cladatum;
2845 	ebitmap_t classmap;
2846 	constraint_expr_t *e;
2847 	int depth;
2848 	unsigned char useexpr = 1;
2849 
2850 	if (pass == 1) {
2851 		while ((id = queue_remove(id_queue)))
2852 			free(id);
2853 		return 0;
2854 	}
2855 
2856 	depth = -1;
2857 	for (e = expr; e; e = e->next) {
2858 		switch (e->expr_type) {
2859 		case CEXPR_NOT:
2860 			if (depth < 0) {
2861 				yyerror("illegal validatetrans expression");
2862 				return -1;
2863 			}
2864 			break;
2865 		case CEXPR_AND:
2866 		case CEXPR_OR:
2867 			if (depth < 1) {
2868 				yyerror("illegal validatetrans expression");
2869 				return -1;
2870 			}
2871 			depth--;
2872 			break;
2873 		case CEXPR_ATTR:
2874 		case CEXPR_NAMES:
2875 			if (depth == (CEXPR_MAXDEPTH - 1)) {
2876 				yyerror("validatetrans expression is too deep");
2877 				return -1;
2878 			}
2879 			depth++;
2880 			break;
2881 		default:
2882 			yyerror("illegal validatetrans expression");
2883 			return -1;
2884 		}
2885 	}
2886 	if (depth != 0) {
2887 		yyerror("illegal validatetrans expression");
2888 		return -1;
2889 	}
2890 
2891 	ebitmap_init(&classmap);
2892 	while ((id = queue_remove(id_queue))) {
2893 		if (!is_id_in_scope(SYM_CLASSES, id)) {
2894 			yyerror2("class %s is not within scope", id);
2895 			free(id);
2896 			return -1;
2897 		}
2898 		cladatum =
2899 		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2900 						     (hashtab_key_t) id);
2901 		if (!cladatum) {
2902 			yyerror2("class %s is not defined", id);
2903 			ebitmap_destroy(&classmap);
2904 			free(id);
2905 			return -1;
2906 		}
2907 		if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
2908 			yyerror("out of memory");
2909 			ebitmap_destroy(&classmap);
2910 			free(id);
2911 			return -1;
2912 		}
2913 
2914 		node = malloc(sizeof(struct constraint_node));
2915 		if (!node) {
2916 			yyerror("out of memory");
2917 			return -1;
2918 		}
2919 		memset(node, 0, sizeof(constraint_node_t));
2920 		if (useexpr) {
2921 			node->expr = expr;
2922 			useexpr = 0;
2923 		} else {
2924 			node->expr = constraint_expr_clone(expr);
2925 		}
2926 		node->permissions = 0;
2927 
2928 		node->next = cladatum->validatetrans;
2929 		cladatum->validatetrans = node;
2930 
2931 		free(id);
2932 	}
2933 
2934 	ebitmap_destroy(&classmap);
2935 
2936 	return 0;
2937 }
2938 
define_cexpr(uint32_t expr_type,uintptr_t arg1,uintptr_t arg2)2939 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
2940 {
2941 	struct constraint_expr *expr, *e1 = NULL, *e2;
2942 	user_datum_t *user;
2943 	role_datum_t *role;
2944 	ebitmap_t negset;
2945 	char *id;
2946 	uint32_t val;
2947 	int add = 1;
2948 
2949 	if (pass == 1) {
2950 		if (expr_type == CEXPR_NAMES) {
2951 			while ((id = queue_remove(id_queue)))
2952 				free(id);
2953 		}
2954 		return 1;	/* any non-NULL value */
2955 	}
2956 
2957 	if ((expr = malloc(sizeof(*expr))) == NULL ||
2958 	    constraint_expr_init(expr) == -1) {
2959 		yyerror("out of memory");
2960 		free(expr);
2961 		return 0;
2962 	}
2963 	expr->expr_type = expr_type;
2964 
2965 	switch (expr_type) {
2966 	case CEXPR_NOT:
2967 		e1 = NULL;
2968 		e2 = (struct constraint_expr *)arg1;
2969 		while (e2) {
2970 			e1 = e2;
2971 			e2 = e2->next;
2972 		}
2973 		if (!e1 || e1->next) {
2974 			yyerror("illegal constraint expression");
2975 			constraint_expr_destroy(expr);
2976 			return 0;
2977 		}
2978 		e1->next = expr;
2979 		return arg1;
2980 	case CEXPR_AND:
2981 	case CEXPR_OR:
2982 		e1 = NULL;
2983 		e2 = (struct constraint_expr *)arg1;
2984 		while (e2) {
2985 			e1 = e2;
2986 			e2 = e2->next;
2987 		}
2988 		if (!e1 || e1->next) {
2989 			yyerror("illegal constraint expression");
2990 			constraint_expr_destroy(expr);
2991 			return 0;
2992 		}
2993 		e1->next = (struct constraint_expr *)arg2;
2994 
2995 		e1 = NULL;
2996 		e2 = (struct constraint_expr *)arg2;
2997 		while (e2) {
2998 			e1 = e2;
2999 			e2 = e2->next;
3000 		}
3001 		if (!e1 || e1->next) {
3002 			yyerror("illegal constraint expression");
3003 			constraint_expr_destroy(expr);
3004 			return 0;
3005 		}
3006 		e1->next = expr;
3007 		return arg1;
3008 	case CEXPR_ATTR:
3009 		expr->attr = arg1;
3010 		expr->op = arg2;
3011 		return (uintptr_t) expr;
3012 	case CEXPR_NAMES:
3013 		add = 1;
3014 		expr->attr = arg1;
3015 		expr->op = arg2;
3016 		ebitmap_init(&negset);
3017 		while ((id = (char *)queue_remove(id_queue))) {
3018 			if (expr->attr & CEXPR_USER) {
3019 				if (!is_id_in_scope(SYM_USERS, id)) {
3020 					yyerror2("user %s is not within scope",
3021 						 id);
3022 					constraint_expr_destroy(expr);
3023 					return 0;
3024 				}
3025 				user =
3026 				    (user_datum_t *) hashtab_search(policydbp->
3027 								    p_users.
3028 								    table,
3029 								    (hashtab_key_t)
3030 								    id);
3031 				if (!user) {
3032 					yyerror2("unknown user %s", id);
3033 					constraint_expr_destroy(expr);
3034 					return 0;
3035 				}
3036 				val = user->s.value;
3037 			} else if (expr->attr & CEXPR_ROLE) {
3038 				if (!is_id_in_scope(SYM_ROLES, id)) {
3039 					yyerror2("role %s is not within scope",
3040 						 id);
3041 					constraint_expr_destroy(expr);
3042 					return 0;
3043 				}
3044 				role =
3045 				    (role_datum_t *) hashtab_search(policydbp->
3046 								    p_roles.
3047 								    table,
3048 								    (hashtab_key_t)
3049 								    id);
3050 				if (!role) {
3051 					yyerror2("unknown role %s", id);
3052 					constraint_expr_destroy(expr);
3053 					return 0;
3054 				}
3055 				val = role->s.value;
3056 			} else if (expr->attr & CEXPR_TYPE) {
3057 				if (set_types(expr->type_names, id, &add, 0)) {
3058 					constraint_expr_destroy(expr);
3059 					return 0;
3060 				}
3061 				continue;
3062 			} else {
3063 				yyerror("invalid constraint expression");
3064 				constraint_expr_destroy(expr);
3065 				return 0;
3066 			}
3067 			if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3068 				yyerror("out of memory");
3069 				ebitmap_destroy(&expr->names);
3070 				constraint_expr_destroy(expr);
3071 				return 0;
3072 			}
3073 			free(id);
3074 		}
3075 		ebitmap_destroy(&negset);
3076 		return (uintptr_t) expr;
3077 	default:
3078 		yyerror("invalid constraint expression");
3079 		constraint_expr_destroy(expr);
3080 		return 0;
3081 	}
3082 
3083 	yyerror("invalid constraint expression");
3084 	free(expr);
3085 	return 0;
3086 }
3087 
define_conditional(cond_expr_t * expr,avrule_t * t,avrule_t * f)3088 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
3089 {
3090 	cond_expr_t *e;
3091 	int depth;
3092 	cond_node_t cn, *cn_old;
3093 
3094 	/* expression cannot be NULL */
3095 	if (!expr) {
3096 		yyerror("illegal conditional expression");
3097 		return -1;
3098 	}
3099 	if (!t) {
3100 		if (!f) {
3101 			/* empty is fine, destroy expression and return */
3102 			cond_expr_destroy(expr);
3103 			return 0;
3104 		}
3105 		/* Invert */
3106 		t = f;
3107 		f = 0;
3108 		expr = define_cond_expr(COND_NOT, expr, 0);
3109 		if (!expr) {
3110 			yyerror("unable to invert");
3111 			return -1;
3112 		}
3113 	}
3114 
3115 	/* verify expression */
3116 	depth = -1;
3117 	for (e = expr; e; e = e->next) {
3118 		switch (e->expr_type) {
3119 		case COND_NOT:
3120 			if (depth < 0) {
3121 				yyerror
3122 				    ("illegal conditional expression; Bad NOT");
3123 				return -1;
3124 			}
3125 			break;
3126 		case COND_AND:
3127 		case COND_OR:
3128 		case COND_XOR:
3129 		case COND_EQ:
3130 		case COND_NEQ:
3131 			if (depth < 1) {
3132 				yyerror
3133 				    ("illegal conditional expression; Bad binary op");
3134 				return -1;
3135 			}
3136 			depth--;
3137 			break;
3138 		case COND_BOOL:
3139 			if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3140 				yyerror
3141 				    ("conditional expression is like totally too deep");
3142 				return -1;
3143 			}
3144 			depth++;
3145 			break;
3146 		default:
3147 			yyerror("illegal conditional expression");
3148 			return -1;
3149 		}
3150 	}
3151 	if (depth != 0) {
3152 		yyerror("illegal conditional expression");
3153 		return -1;
3154 	}
3155 
3156 	/*  use tmp conditional node to partially build new node */
3157 	memset(&cn, 0, sizeof(cn));
3158 	cn.expr = expr;
3159 	cn.avtrue_list = t;
3160 	cn.avfalse_list = f;
3161 
3162 	/* normalize/precompute expression */
3163 	if (cond_normalize_expr(policydbp, &cn) < 0) {
3164 		yyerror("problem normalizing conditional expression");
3165 		return -1;
3166 	}
3167 
3168 	/* get the existing conditional node, or create a new one */
3169 	cn_old = get_current_cond_list(&cn);
3170 	if (!cn_old) {
3171 		return -1;
3172 	}
3173 
3174 	append_cond_list(&cn);
3175 
3176 	/* note that there is no check here for duplicate rules, nor
3177 	 * check that rule already exists in base -- that will be
3178 	 * handled during conditional expansion, in expand.c */
3179 
3180 	cn.avtrue_list = NULL;
3181 	cn.avfalse_list = NULL;
3182 	cond_node_destroy(&cn);
3183 
3184 	return 0;
3185 }
3186 
define_cond_expr(uint32_t expr_type,void * arg1,void * arg2)3187 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3188 {
3189 	struct cond_expr *expr, *e1 = NULL, *e2;
3190 	cond_bool_datum_t *bool_var;
3191 	char *id;
3192 
3193 	/* expressions are handled in the second pass */
3194 	if (pass == 1) {
3195 		if (expr_type == COND_BOOL) {
3196 			while ((id = queue_remove(id_queue))) {
3197 				free(id);
3198 			}
3199 		}
3200 		return (cond_expr_t *) 1;	/* any non-NULL value */
3201 	}
3202 
3203 	/* create a new expression struct */
3204 	expr = malloc(sizeof(struct cond_expr));
3205 	if (!expr) {
3206 		yyerror("out of memory");
3207 		return NULL;
3208 	}
3209 	memset(expr, 0, sizeof(cond_expr_t));
3210 	expr->expr_type = expr_type;
3211 
3212 	/* create the type asked for */
3213 	switch (expr_type) {
3214 	case COND_NOT:
3215 		e1 = NULL;
3216 		e2 = (struct cond_expr *)arg1;
3217 		while (e2) {
3218 			e1 = e2;
3219 			e2 = e2->next;
3220 		}
3221 		if (!e1 || e1->next) {
3222 			yyerror("illegal conditional NOT expression");
3223 			free(expr);
3224 			return NULL;
3225 		}
3226 		e1->next = expr;
3227 		return (struct cond_expr *)arg1;
3228 	case COND_AND:
3229 	case COND_OR:
3230 	case COND_XOR:
3231 	case COND_EQ:
3232 	case COND_NEQ:
3233 		e1 = NULL;
3234 		e2 = (struct cond_expr *)arg1;
3235 		while (e2) {
3236 			e1 = e2;
3237 			e2 = e2->next;
3238 		}
3239 		if (!e1 || e1->next) {
3240 			yyerror
3241 			    ("illegal left side of conditional binary op expression");
3242 			free(expr);
3243 			return NULL;
3244 		}
3245 		e1->next = (struct cond_expr *)arg2;
3246 
3247 		e1 = NULL;
3248 		e2 = (struct cond_expr *)arg2;
3249 		while (e2) {
3250 			e1 = e2;
3251 			e2 = e2->next;
3252 		}
3253 		if (!e1 || e1->next) {
3254 			yyerror
3255 			    ("illegal right side of conditional binary op expression");
3256 			free(expr);
3257 			return NULL;
3258 		}
3259 		e1->next = expr;
3260 		return (struct cond_expr *)arg1;
3261 	case COND_BOOL:
3262 		id = (char *)queue_remove(id_queue);
3263 		if (!id) {
3264 			yyerror("bad conditional; expected boolean id");
3265 			free(id);
3266 			free(expr);
3267 			return NULL;
3268 		}
3269 		if (!is_id_in_scope(SYM_BOOLS, id)) {
3270 			yyerror2("boolean %s is not within scope", id);
3271 			free(id);
3272 			free(expr);
3273 			return NULL;
3274 		}
3275 		bool_var =
3276 		    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
3277 							 table,
3278 							 (hashtab_key_t) id);
3279 		if (!bool_var) {
3280 			yyerror2("unknown boolean %s in conditional expression",
3281 				 id);
3282 			free(expr);
3283 			free(id);
3284 			return NULL;
3285 		}
3286 		expr->bool = bool_var->s.value;
3287 		free(id);
3288 		return expr;
3289 	default:
3290 		yyerror("illegal conditional expression");
3291 		free(expr);
3292 		return NULL;
3293 	}
3294 }
3295 
set_user_roles(role_set_t * set,char * id)3296 static int set_user_roles(role_set_t * set, char *id)
3297 {
3298 	role_datum_t *r;
3299 	unsigned int i;
3300 	ebitmap_node_t *node;
3301 
3302 	if (strcmp(id, "*") == 0) {
3303 		free(id);
3304 		yyerror("* is not allowed in user declarations");
3305 		return -1;
3306 	}
3307 
3308 	if (strcmp(id, "~") == 0) {
3309 		free(id);
3310 		yyerror("~ is not allowed in user declarations");
3311 		return -1;
3312 	}
3313 
3314 	if (!is_id_in_scope(SYM_ROLES, id)) {
3315 		yyerror2("role %s is not within scope", id);
3316 		free(id);
3317 		return -1;
3318 	}
3319 	r = hashtab_search(policydbp->p_roles.table, id);
3320 	if (!r) {
3321 		yyerror2("unknown role %s", id);
3322 		free(id);
3323 		return -1;
3324 	}
3325 
3326 	/* set the role and every role it dominates */
3327 	ebitmap_for_each_bit(&r->dominates, node, i) {
3328 		if (ebitmap_node_get_bit(node, i))
3329 			if (ebitmap_set_bit(&set->roles, i, TRUE))
3330 				goto oom;
3331 	}
3332 	free(id);
3333 	return 0;
3334       oom:
3335 	yyerror("out of memory");
3336 	return -1;
3337 }
3338 
parse_categories(char * id,level_datum_t * levdatum,ebitmap_t * cats)3339 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
3340 {
3341 	cat_datum_t *cdatum;
3342 	int range_start, range_end, i;
3343 
3344 	if (id_has_dot(id)) {
3345 		char *id_start = id;
3346 		char *id_end = strchr(id, '.');
3347 
3348 		*(id_end++) = '\0';
3349 
3350 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3351 							(hashtab_key_t)
3352 							id_start);
3353 		if (!cdatum) {
3354 			yyerror2("unknown category %s", id_start);
3355 			return -1;
3356 		}
3357 		range_start = cdatum->s.value - 1;
3358 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3359 							(hashtab_key_t) id_end);
3360 		if (!cdatum) {
3361 			yyerror2("unknown category %s", id_end);
3362 			return -1;
3363 		}
3364 		range_end = cdatum->s.value - 1;
3365 
3366 		if (range_end < range_start) {
3367 			yyerror2("category range is invalid");
3368 			return -1;
3369 		}
3370 	} else {
3371 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3372 							(hashtab_key_t) id);
3373 		if (!cdatum) {
3374 			yyerror2("unknown category %s", id);
3375 			return -1;
3376 		}
3377 		range_start = range_end = cdatum->s.value - 1;
3378 	}
3379 
3380 	for (i = range_start; i <= range_end; i++) {
3381 		if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
3382 			uint32_t level_value = levdatum->level->sens - 1;
3383 			policydb_index_others(NULL, policydbp, 0);
3384 			yyerror2("category %s can not be associated "
3385 				 "with level %s",
3386 				 policydbp->p_cat_val_to_name[i],
3387 				 policydbp->p_sens_val_to_name[level_value]);
3388 			return -1;
3389 		}
3390 		if (ebitmap_set_bit(cats, i, TRUE)) {
3391 			yyerror("out of memory");
3392 			return -1;
3393 		}
3394 	}
3395 
3396 	return 0;
3397 }
3398 
parse_semantic_categories(char * id,level_datum_t * levdatum,mls_semantic_cat_t ** cats)3399 static int parse_semantic_categories(char *id, level_datum_t * levdatum,
3400 				     mls_semantic_cat_t ** cats)
3401 {
3402 	cat_datum_t *cdatum;
3403 	mls_semantic_cat_t *newcat;
3404 	unsigned int range_start, range_end;
3405 
3406 	if (id_has_dot(id)) {
3407 		char *id_start = id;
3408 		char *id_end = strchr(id, '.');
3409 
3410 		*(id_end++) = '\0';
3411 
3412 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3413 							(hashtab_key_t)
3414 							id_start);
3415 		if (!cdatum) {
3416 			yyerror2("unknown category %s", id_start);
3417 			return -1;
3418 		}
3419 		range_start = cdatum->s.value;
3420 
3421 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3422 							(hashtab_key_t) id_end);
3423 		if (!cdatum) {
3424 			yyerror2("unknown category %s", id_end);
3425 			return -1;
3426 		}
3427 		range_end = cdatum->s.value;
3428 	} else {
3429 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3430 							(hashtab_key_t) id);
3431 		if (!cdatum) {
3432 			yyerror2("unknown category %s", id);
3433 			return -1;
3434 		}
3435 		range_start = range_end = cdatum->s.value;
3436 	}
3437 
3438 	newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
3439 	if (!newcat) {
3440 		yyerror("out of memory");
3441 		return -1;
3442 	}
3443 
3444 	mls_semantic_cat_init(newcat);
3445 	newcat->next = *cats;
3446 	newcat->low = range_start;
3447 	newcat->high = range_end;
3448 
3449 	*cats = newcat;
3450 
3451 	return 0;
3452 }
3453 
define_user(void)3454 int define_user(void)
3455 {
3456 	char *id;
3457 	user_datum_t *usrdatum;
3458 	level_datum_t *levdatum;
3459 	int l;
3460 
3461 	if (pass == 1) {
3462 		while ((id = queue_remove(id_queue)))
3463 			free(id);
3464 		if (mlspol) {
3465 			while ((id = queue_remove(id_queue)))
3466 				free(id);
3467 			id = queue_remove(id_queue);
3468 			free(id);
3469 			for (l = 0; l < 2; l++) {
3470 				while ((id = queue_remove(id_queue))) {
3471 					free(id);
3472 				}
3473 				id = queue_remove(id_queue);
3474 				if (!id)
3475 					break;
3476 				free(id);
3477 			}
3478 		}
3479 		return 0;
3480 	}
3481 
3482 	if ((usrdatum = declare_user()) == NULL) {
3483 		return -1;
3484 	}
3485 
3486 	while ((id = queue_remove(id_queue))) {
3487 		if (set_user_roles(&usrdatum->roles, id))
3488 			continue;
3489 	}
3490 
3491 	if (mlspol) {
3492 		id = queue_remove(id_queue);
3493 		if (!id) {
3494 			yyerror("no default level specified for user");
3495 			return -1;
3496 		}
3497 
3498 		levdatum = (level_datum_t *)
3499 		    hashtab_search(policydbp->p_levels.table,
3500 				   (hashtab_key_t) id);
3501 		if (!levdatum) {
3502 			yyerror2("unknown sensitivity %s used in user"
3503 				 " level definition", id);
3504 			free(id);
3505 			return -1;
3506 		}
3507 		free(id);
3508 
3509 		usrdatum->dfltlevel.sens = levdatum->level->sens;
3510 
3511 		while ((id = queue_remove(id_queue))) {
3512 			if (parse_semantic_categories(id, levdatum,
3513 			                            &usrdatum->dfltlevel.cat)) {
3514 				free(id);
3515 				return -1;
3516 			}
3517 			free(id);
3518 		}
3519 
3520 		id = queue_remove(id_queue);
3521 
3522 		for (l = 0; l < 2; l++) {
3523 			levdatum = (level_datum_t *)
3524 			    hashtab_search(policydbp->p_levels.table,
3525 					   (hashtab_key_t) id);
3526 			if (!levdatum) {
3527 				yyerror2("unknown sensitivity %s used in user"
3528 					 " range definition", id);
3529 				free(id);
3530 				return -1;
3531 			}
3532 			free(id);
3533 
3534 			usrdatum->range.level[l].sens = levdatum->level->sens;
3535 
3536 			while ((id = queue_remove(id_queue))) {
3537 				if (parse_semantic_categories(id, levdatum,
3538 				               &usrdatum->range.level[l].cat)) {
3539 					free(id);
3540 					return -1;
3541 				}
3542 				free(id);
3543 			}
3544 
3545 			id = queue_remove(id_queue);
3546 			if (!id)
3547 				break;
3548 		}
3549 
3550 		if (l == 0) {
3551 			if (mls_semantic_level_cpy(&usrdatum->range.level[1],
3552 			                           &usrdatum->range.level[0])) {
3553 				yyerror("out of memory");
3554 				return -1;
3555 			}
3556 		}
3557 	}
3558 	return 0;
3559 }
3560 
parse_security_context(context_struct_t * c)3561 static int parse_security_context(context_struct_t * c)
3562 {
3563 	char *id;
3564 	role_datum_t *role;
3565 	type_datum_t *typdatum;
3566 	user_datum_t *usrdatum;
3567 	level_datum_t *levdatum;
3568 	int l;
3569 
3570 	if (pass == 1) {
3571 		id = queue_remove(id_queue);
3572 		free(id);	/* user  */
3573 		id = queue_remove(id_queue);
3574 		free(id);	/* role  */
3575 		id = queue_remove(id_queue);
3576 		free(id);	/* type  */
3577 		if (mlspol) {
3578 			id = queue_remove(id_queue);
3579 			free(id);
3580 			for (l = 0; l < 2; l++) {
3581 				while ((id = queue_remove(id_queue))) {
3582 					free(id);
3583 				}
3584 				id = queue_remove(id_queue);
3585 				if (!id)
3586 					break;
3587 				free(id);
3588 			}
3589 		}
3590 		return 0;
3591 	}
3592 
3593 	/* check context c to make sure ok to dereference c later */
3594 	if (c == NULL) {
3595 		yyerror("null context pointer!");
3596 		return -1;
3597 	}
3598 
3599 	context_init(c);
3600 
3601 	/* extract the user */
3602 	id = queue_remove(id_queue);
3603 	if (!id) {
3604 		yyerror("no effective user?");
3605 		goto bad;
3606 	}
3607 	if (!is_id_in_scope(SYM_USERS, id)) {
3608 		yyerror2("user %s is not within scope", id);
3609 		free(id);
3610 		goto bad;
3611 	}
3612 	usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3613 						   (hashtab_key_t) id);
3614 	if (!usrdatum) {
3615 		yyerror2("user %s is not defined", id);
3616 		free(id);
3617 		goto bad;
3618 	}
3619 	c->user = usrdatum->s.value;
3620 
3621 	/* no need to keep the user name */
3622 	free(id);
3623 
3624 	/* extract the role */
3625 	id = (char *)queue_remove(id_queue);
3626 	if (!id) {
3627 		yyerror("no role name for sid context definition?");
3628 		return -1;
3629 	}
3630 	if (!is_id_in_scope(SYM_ROLES, id)) {
3631 		yyerror2("role %s is not within scope", id);
3632 		free(id);
3633 		return -1;
3634 	}
3635 	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
3636 					       (hashtab_key_t) id);
3637 	if (!role) {
3638 		yyerror2("role %s is not defined", id);
3639 		free(id);
3640 		return -1;
3641 	}
3642 	c->role = role->s.value;
3643 
3644 	/* no need to keep the role name */
3645 	free(id);
3646 
3647 	/* extract the type */
3648 	id = (char *)queue_remove(id_queue);
3649 	if (!id) {
3650 		yyerror("no type name for sid context definition?");
3651 		return -1;
3652 	}
3653 	if (!is_id_in_scope(SYM_TYPES, id)) {
3654 		yyerror2("type %s is not within scope", id);
3655 		free(id);
3656 		return -1;
3657 	}
3658 	typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
3659 						   (hashtab_key_t) id);
3660 	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
3661 		yyerror2("type %s is not defined or is an attribute", id);
3662 		free(id);
3663 		return -1;
3664 	}
3665 	c->type = typdatum->s.value;
3666 
3667 	/* no need to keep the type name */
3668 	free(id);
3669 
3670 	if (mlspol) {
3671 		/* extract the low sensitivity */
3672 		id = (char *)queue_head(id_queue);
3673 		if (!id) {
3674 			yyerror("no sensitivity name for sid context"
3675 				" definition?");
3676 			return -1;
3677 		}
3678 
3679 		id = (char *)queue_remove(id_queue);
3680 		for (l = 0; l < 2; l++) {
3681 			levdatum = (level_datum_t *)
3682 			    hashtab_search(policydbp->p_levels.table,
3683 					   (hashtab_key_t) id);
3684 			if (!levdatum) {
3685 				yyerror2("Sensitivity %s is not defined", id);
3686 				free(id);
3687 				return -1;
3688 			}
3689 			free(id);
3690 			c->range.level[l].sens = levdatum->level->sens;
3691 
3692 			/* extract low category set */
3693 			while ((id = queue_remove(id_queue))) {
3694 				if (parse_categories(id, levdatum,
3695 						     &c->range.level[l].cat)) {
3696 					free(id);
3697 					return -1;
3698 				}
3699 				free(id);
3700 			}
3701 
3702 			/* extract high sensitivity */
3703 			id = (char *)queue_remove(id_queue);
3704 			if (!id)
3705 				break;
3706 		}
3707 
3708 		if (l == 0) {
3709 			c->range.level[1].sens = c->range.level[0].sens;
3710 			if (ebitmap_cpy(&c->range.level[1].cat,
3711 					&c->range.level[0].cat)) {
3712 
3713 				yyerror("out of memory");
3714 				goto bad;
3715 			}
3716 		}
3717 	}
3718 
3719 	if (!policydb_context_isvalid(policydbp, c)) {
3720 		yyerror("invalid security context");
3721 		goto bad;
3722 	}
3723 	return 0;
3724 
3725       bad:
3726 	context_destroy(c);
3727 
3728 	return -1;
3729 }
3730 
define_initial_sid_context(void)3731 int define_initial_sid_context(void)
3732 {
3733 	char *id;
3734 	ocontext_t *c, *head;
3735 
3736 	if (pass == 1) {
3737 		id = (char *)queue_remove(id_queue);
3738 		free(id);
3739 		parse_security_context(NULL);
3740 		return 0;
3741 	}
3742 
3743 	id = (char *)queue_remove(id_queue);
3744 	if (!id) {
3745 		yyerror("no sid name for SID context definition?");
3746 		return -1;
3747 	}
3748 	head = policydbp->ocontexts[OCON_ISID];
3749 	for (c = head; c; c = c->next) {
3750 		if (!strcmp(id, c->u.name))
3751 			break;
3752 	}
3753 
3754 	if (!c) {
3755 		yyerror2("SID %s is not defined", id);
3756 		free(id);
3757 		return -1;
3758 	}
3759 	if (c->context[0].user) {
3760 		yyerror2("The context for SID %s is multiply defined", id);
3761 		free(id);
3762 		return -1;
3763 	}
3764 	/* no need to keep the sid name */
3765 	free(id);
3766 
3767 	if (parse_security_context(&c->context[0]))
3768 		return -1;
3769 
3770 	return 0;
3771 }
3772 
define_fs_context(unsigned int major,unsigned int minor)3773 int define_fs_context(unsigned int major, unsigned int minor)
3774 {
3775 	ocontext_t *newc, *c, *head;
3776 
3777 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
3778 		yyerror("fscon not supported for target");
3779 		return -1;
3780 	}
3781 
3782 	if (pass == 1) {
3783 		parse_security_context(NULL);
3784 		parse_security_context(NULL);
3785 		return 0;
3786 	}
3787 
3788 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3789 	if (!newc) {
3790 		yyerror("out of memory");
3791 		return -1;
3792 	}
3793 	memset(newc, 0, sizeof(ocontext_t));
3794 
3795 	newc->u.name = (char *)malloc(6);
3796 	if (!newc->u.name) {
3797 		yyerror("out of memory");
3798 		free(newc);
3799 		return -1;
3800 	}
3801 	sprintf(newc->u.name, "%02x:%02x", major, minor);
3802 
3803 	if (parse_security_context(&newc->context[0])) {
3804 		free(newc->u.name);
3805 		free(newc);
3806 		return -1;
3807 	}
3808 	if (parse_security_context(&newc->context[1])) {
3809 		context_destroy(&newc->context[0]);
3810 		free(newc->u.name);
3811 		free(newc);
3812 		return -1;
3813 	}
3814 	head = policydbp->ocontexts[OCON_FS];
3815 
3816 	for (c = head; c; c = c->next) {
3817 		if (!strcmp(newc->u.name, c->u.name)) {
3818 			yyerror2("duplicate entry for file system %s",
3819 				 newc->u.name);
3820 			context_destroy(&newc->context[0]);
3821 			context_destroy(&newc->context[1]);
3822 			free(newc->u.name);
3823 			free(newc);
3824 			return -1;
3825 		}
3826 	}
3827 
3828 	newc->next = head;
3829 	policydbp->ocontexts[OCON_FS] = newc;
3830 
3831 	return 0;
3832 }
3833 
define_pirq_context(unsigned int pirq)3834 int define_pirq_context(unsigned int pirq)
3835 {
3836 	ocontext_t *newc, *c, *l, *head;
3837 	char *id;
3838 
3839 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3840 		yyerror("pirqcon not supported for target");
3841 		return -1;
3842 	}
3843 
3844 	if (pass == 1) {
3845 		id = (char *) queue_remove(id_queue);
3846 		free(id);
3847 		parse_security_context(NULL);
3848 		return 0;
3849 	}
3850 
3851 	newc = malloc(sizeof(ocontext_t));
3852 	if (!newc) {
3853 		yyerror("out of memory");
3854 		return -1;
3855 	}
3856 	memset(newc, 0, sizeof(ocontext_t));
3857 
3858 	newc->u.pirq = pirq;
3859 
3860 	if (parse_security_context(&newc->context[0])) {
3861 		free(newc);
3862 		return -1;
3863 	}
3864 
3865 	head = policydbp->ocontexts[OCON_XEN_PIRQ];
3866 	for (l = NULL, c = head; c; l = c, c = c->next) {
3867 		unsigned int pirq2;
3868 
3869 		pirq2 = c->u.pirq;
3870 		if (pirq == pirq2) {
3871 			yyerror2("duplicate pirqcon entry for %d ", pirq);
3872 			goto bad;
3873 		}
3874 	}
3875 
3876 	if (l)
3877 		l->next = newc;
3878 	else
3879 		policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
3880 
3881 	return 0;
3882 
3883 bad:
3884 	free(newc);
3885 	return -1;
3886 }
3887 
define_iomem_context(unsigned long low,unsigned long high)3888 int define_iomem_context(unsigned long low, unsigned long high)
3889 {
3890 	ocontext_t *newc, *c, *l, *head;
3891 	char *id;
3892 
3893 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3894 		yyerror("iomemcon not supported for target");
3895 		return -1;
3896 	}
3897 
3898 	if (pass == 1) {
3899 		id = (char *)queue_remove(id_queue);
3900 		free(id);
3901 		parse_security_context(NULL);
3902 		return 0;
3903 	}
3904 
3905 	newc = malloc(sizeof(ocontext_t));
3906 	if (!newc) {
3907 		yyerror("out of memory");
3908 		return -1;
3909 	}
3910 	memset(newc, 0, sizeof(ocontext_t));
3911 
3912 	newc->u.iomem.low_iomem  = low;
3913 	newc->u.iomem.high_iomem = high;
3914 
3915 	if (low > high) {
3916 		yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high);
3917 		free(newc);
3918 		return -1;
3919 	}
3920 
3921 	if (parse_security_context(&newc->context[0])) {
3922 		free(newc);
3923 		return -1;
3924 	}
3925 
3926 	head = policydbp->ocontexts[OCON_XEN_IOMEM];
3927 	for (l = NULL, c = head; c; l = c, c = c->next) {
3928 		unsigned int low2, high2;
3929 
3930 		low2 = c->u.iomem.low_iomem;
3931 		high2 = c->u.iomem.high_iomem;
3932 		if (low <= high2 && low2 <= high) {
3933 			yyerror2("iomemcon entry for 0x%x-0x%x overlaps with "
3934 				"earlier entry 0x%x-0x%x", low, high,
3935 				low2, high2);
3936 			goto bad;
3937 		}
3938 	}
3939 
3940 	if (l)
3941 		l->next = newc;
3942 	else
3943 		policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
3944 
3945 	return 0;
3946 
3947 bad:
3948 	free(newc);
3949 	return -1;
3950 }
3951 
define_ioport_context(unsigned long low,unsigned long high)3952 int define_ioport_context(unsigned long low, unsigned long high)
3953 {
3954 	ocontext_t *newc, *c, *l, *head;
3955 	char *id;
3956 
3957 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3958 		yyerror("ioportcon not supported for target");
3959 		return -1;
3960 	}
3961 
3962 	if (pass == 1) {
3963 		id = (char *)queue_remove(id_queue);
3964 		free(id);
3965 		parse_security_context(NULL);
3966 		return 0;
3967 	}
3968 
3969 	newc = malloc(sizeof(ocontext_t));
3970 	if (!newc) {
3971 		yyerror("out of memory");
3972 		return -1;
3973 	}
3974 	memset(newc, 0, sizeof(ocontext_t));
3975 
3976 	newc->u.ioport.low_ioport  = low;
3977 	newc->u.ioport.high_ioport = high;
3978 
3979 	if (low > high) {
3980 		yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high);
3981 		free(newc);
3982 		return -1;
3983 	}
3984 
3985 	if (parse_security_context(&newc->context[0])) {
3986 		free(newc);
3987 		return -1;
3988 	}
3989 
3990 	head = policydbp->ocontexts[OCON_XEN_IOPORT];
3991 	for (l = NULL, c = head; c; l = c, c = c->next) {
3992 		unsigned int low2, high2;
3993 
3994 		low2 = c->u.ioport.low_ioport;
3995 		high2 = c->u.ioport.high_ioport;
3996 		if (low <= high2 && low2 <= high) {
3997 			yyerror2("ioportcon entry for 0x%x-0x%x overlaps with"
3998 				"earlier entry 0x%x-0x%x", low, high,
3999 				low2, high2);
4000 			goto bad;
4001 		}
4002 	}
4003 
4004 	if (l)
4005 		l->next = newc;
4006 	else
4007 		policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
4008 
4009 	return 0;
4010 
4011 bad:
4012 	free(newc);
4013 	return -1;
4014 }
4015 
define_pcidevice_context(unsigned long device)4016 int define_pcidevice_context(unsigned long device)
4017 {
4018 	ocontext_t *newc, *c, *l, *head;
4019 	char *id;
4020 
4021 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4022 		yyerror("pcidevicecon not supported for target");
4023 		return -1;
4024 	}
4025 
4026 	if (pass == 1) {
4027 		id = (char *) queue_remove(id_queue);
4028 		free(id);
4029 		parse_security_context(NULL);
4030 		return 0;
4031 	}
4032 
4033 	newc = malloc(sizeof(ocontext_t));
4034 	if (!newc) {
4035 		yyerror("out of memory");
4036 		return -1;
4037 	}
4038 	memset(newc, 0, sizeof(ocontext_t));
4039 
4040 	newc->u.device = device;
4041 
4042 	if (parse_security_context(&newc->context[0])) {
4043 		free(newc);
4044 		return -1;
4045 	}
4046 
4047 	head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
4048 	for (l = NULL, c = head; c; l = c, c = c->next) {
4049 		unsigned int device2;
4050 
4051 		device2 = c->u.device;
4052 		if (device == device2) {
4053 			yyerror2("duplicate pcidevicecon entry for 0x%x ",
4054 				 device);
4055 			goto bad;
4056 		}
4057 	}
4058 
4059 	if (l)
4060 		l->next = newc;
4061 	else
4062 		policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
4063 
4064 	return 0;
4065 
4066 bad:
4067 	free(newc);
4068 	return -1;
4069 }
4070 
define_port_context(unsigned int low,unsigned int high)4071 int define_port_context(unsigned int low, unsigned int high)
4072 {
4073 	ocontext_t *newc, *c, *l, *head;
4074 	unsigned int protocol;
4075 	char *id;
4076 
4077 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4078 		yyerror("portcon not supported for target");
4079 		return -1;
4080 	}
4081 
4082 	if (pass == 1) {
4083 		id = (char *)queue_remove(id_queue);
4084 		free(id);
4085 		parse_security_context(NULL);
4086 		return 0;
4087 	}
4088 
4089 	newc = malloc(sizeof(ocontext_t));
4090 	if (!newc) {
4091 		yyerror("out of memory");
4092 		return -1;
4093 	}
4094 	memset(newc, 0, sizeof(ocontext_t));
4095 
4096 	id = (char *)queue_remove(id_queue);
4097 	if (!id) {
4098 		free(newc);
4099 		return -1;
4100 	}
4101 	if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4102 		protocol = IPPROTO_TCP;
4103 	} else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4104 		protocol = IPPROTO_UDP;
4105 	} else {
4106 		yyerror2("unrecognized protocol %s", id);
4107 		free(newc);
4108 		return -1;
4109 	}
4110 
4111 	newc->u.port.protocol = protocol;
4112 	newc->u.port.low_port = low;
4113 	newc->u.port.high_port = high;
4114 
4115 	if (low > high) {
4116 		yyerror2("low port %d exceeds high port %d", low, high);
4117 		free(newc);
4118 		return -1;
4119 	}
4120 
4121 	if (parse_security_context(&newc->context[0])) {
4122 		free(newc);
4123 		return -1;
4124 	}
4125 
4126 	/* Preserve the matching order specified in the configuration. */
4127 	head = policydbp->ocontexts[OCON_PORT];
4128 	for (l = NULL, c = head; c; l = c, c = c->next) {
4129 		unsigned int prot2, low2, high2;
4130 
4131 		prot2 = c->u.port.protocol;
4132 		low2 = c->u.port.low_port;
4133 		high2 = c->u.port.high_port;
4134 		if (protocol != prot2)
4135 			continue;
4136 		if (low == low2 && high == high2) {
4137 			yyerror2("duplicate portcon entry for %s %d-%d ", id,
4138 				 low, high);
4139 			goto bad;
4140 		}
4141 		if (low2 <= low && high2 >= high) {
4142 			yyerror2("portcon entry for %s %d-%d hidden by earlier "
4143 				 "entry for %d-%d", id, low, high, low2, high2);
4144 			goto bad;
4145 		}
4146 	}
4147 
4148 	if (l)
4149 		l->next = newc;
4150 	else
4151 		policydbp->ocontexts[OCON_PORT] = newc;
4152 
4153 	return 0;
4154 
4155       bad:
4156 	free(newc);
4157 	return -1;
4158 }
4159 
define_netif_context(void)4160 int define_netif_context(void)
4161 {
4162 	ocontext_t *newc, *c, *head;
4163 
4164 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4165 		yyerror("netifcon not supported for target");
4166 		return -1;
4167 	}
4168 
4169 	if (pass == 1) {
4170 		free(queue_remove(id_queue));
4171 		parse_security_context(NULL);
4172 		parse_security_context(NULL);
4173 		return 0;
4174 	}
4175 
4176 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4177 	if (!newc) {
4178 		yyerror("out of memory");
4179 		return -1;
4180 	}
4181 	memset(newc, 0, sizeof(ocontext_t));
4182 
4183 	newc->u.name = (char *)queue_remove(id_queue);
4184 	if (!newc->u.name) {
4185 		free(newc);
4186 		return -1;
4187 	}
4188 	if (parse_security_context(&newc->context[0])) {
4189 		free(newc->u.name);
4190 		free(newc);
4191 		return -1;
4192 	}
4193 	if (parse_security_context(&newc->context[1])) {
4194 		context_destroy(&newc->context[0]);
4195 		free(newc->u.name);
4196 		free(newc);
4197 		return -1;
4198 	}
4199 	head = policydbp->ocontexts[OCON_NETIF];
4200 
4201 	for (c = head; c; c = c->next) {
4202 		if (!strcmp(newc->u.name, c->u.name)) {
4203 			yyerror2("duplicate entry for network interface %s",
4204 				 newc->u.name);
4205 			context_destroy(&newc->context[0]);
4206 			context_destroy(&newc->context[1]);
4207 			free(newc->u.name);
4208 			free(newc);
4209 			return -1;
4210 		}
4211 	}
4212 
4213 	newc->next = head;
4214 	policydbp->ocontexts[OCON_NETIF] = newc;
4215 	return 0;
4216 }
4217 
define_ipv4_node_context()4218 int define_ipv4_node_context()
4219 {
4220 	char *id;
4221 	int rc = 0;
4222 	struct in_addr addr, mask;
4223 	ocontext_t *newc, *c, *l, *head;
4224 
4225 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4226 		yyerror("nodecon not supported for target");
4227 		return -1;
4228 	}
4229 
4230 	if (pass == 1) {
4231 		free(queue_remove(id_queue));
4232 		free(queue_remove(id_queue));
4233 		parse_security_context(NULL);
4234 		goto out;
4235 	}
4236 
4237 	id = queue_remove(id_queue);
4238 	if (!id) {
4239 		yyerror("failed to read ipv4 address");
4240 		rc = -1;
4241 		goto out;
4242 	}
4243 
4244 	rc = inet_pton(AF_INET, id, &addr);
4245 	free(id);
4246 	if (rc < 1) {
4247 		yyerror("failed to parse ipv4 address");
4248 		if (rc == 0)
4249 			rc = -1;
4250 		goto out;
4251 	}
4252 
4253 	id = queue_remove(id_queue);
4254 	if (!id) {
4255 		yyerror("failed to read ipv4 address");
4256 		rc = -1;
4257 		goto out;
4258 	}
4259 
4260 	rc = inet_pton(AF_INET, id, &mask);
4261 	free(id);
4262 	if (rc < 1) {
4263 		yyerror("failed to parse ipv4 mask");
4264 		if (rc == 0)
4265 			rc = -1;
4266 		goto out;
4267 	}
4268 
4269 	newc = malloc(sizeof(ocontext_t));
4270 	if (!newc) {
4271 		yyerror("out of memory");
4272 		rc = -1;
4273 		goto out;
4274 	}
4275 
4276 	memset(newc, 0, sizeof(ocontext_t));
4277 	newc->u.node.addr = addr.s_addr;
4278 	newc->u.node.mask = mask.s_addr;
4279 
4280 	if (parse_security_context(&newc->context[0])) {
4281 		free(newc);
4282 		return -1;
4283 	}
4284 
4285 	/* Create order of most specific to least retaining
4286 	   the order specified in the configuration. */
4287 	head = policydbp->ocontexts[OCON_NODE];
4288 	for (l = NULL, c = head; c; l = c, c = c->next) {
4289 		if (newc->u.node.mask > c->u.node.mask)
4290 			break;
4291 	}
4292 
4293 	newc->next = c;
4294 
4295 	if (l)
4296 		l->next = newc;
4297 	else
4298 		policydbp->ocontexts[OCON_NODE] = newc;
4299 	rc = 0;
4300 out:
4301 	return rc;
4302 }
4303 
define_ipv6_node_context(void)4304 int define_ipv6_node_context(void)
4305 {
4306 	char *id;
4307 	int rc = 0;
4308 	struct in6_addr addr, mask;
4309 	ocontext_t *newc, *c, *l, *head;
4310 
4311 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4312 		yyerror("nodecon not supported for target");
4313 		return -1;
4314 	}
4315 
4316 	if (pass == 1) {
4317 		free(queue_remove(id_queue));
4318 		free(queue_remove(id_queue));
4319 		parse_security_context(NULL);
4320 		goto out;
4321 	}
4322 
4323 	id = queue_remove(id_queue);
4324 	if (!id) {
4325 		yyerror("failed to read ipv6 address");
4326 		rc = -1;
4327 		goto out;
4328 	}
4329 
4330 	rc = inet_pton(AF_INET6, id, &addr);
4331 	free(id);
4332 	if (rc < 1) {
4333 		yyerror("failed to parse ipv6 address");
4334 		if (rc == 0)
4335 			rc = -1;
4336 		goto out;
4337 	}
4338 
4339 	id = queue_remove(id_queue);
4340 	if (!id) {
4341 		yyerror("failed to read ipv6 address");
4342 		rc = -1;
4343 		goto out;
4344 	}
4345 
4346 	rc = inet_pton(AF_INET6, id, &mask);
4347 	free(id);
4348 	if (rc < 1) {
4349 		yyerror("failed to parse ipv6 mask");
4350 		if (rc == 0)
4351 			rc = -1;
4352 		goto out;
4353 	}
4354 
4355 	newc = malloc(sizeof(ocontext_t));
4356 	if (!newc) {
4357 		yyerror("out of memory");
4358 		rc = -1;
4359 		goto out;
4360 	}
4361 
4362 	memset(newc, 0, sizeof(ocontext_t));
4363 
4364 #ifdef DARWIN
4365 	memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
4366 	memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
4367 #else
4368 	memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
4369 	memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
4370 #endif
4371 
4372 	if (parse_security_context(&newc->context[0])) {
4373 		free(newc);
4374 		rc = -1;
4375 		goto out;
4376 	}
4377 
4378 	/* Create order of most specific to least retaining
4379 	   the order specified in the configuration. */
4380 	head = policydbp->ocontexts[OCON_NODE6];
4381 	for (l = NULL, c = head; c; l = c, c = c->next) {
4382 		if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
4383 			break;
4384 	}
4385 
4386 	newc->next = c;
4387 
4388 	if (l)
4389 		l->next = newc;
4390 	else
4391 		policydbp->ocontexts[OCON_NODE6] = newc;
4392 
4393 	rc = 0;
4394       out:
4395 	return rc;
4396 }
4397 
define_fs_use(int behavior)4398 int define_fs_use(int behavior)
4399 {
4400 	ocontext_t *newc, *c, *head;
4401 
4402 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4403 		yyerror("fsuse not supported for target");
4404 		return -1;
4405 	}
4406 
4407 	if (pass == 1) {
4408 		free(queue_remove(id_queue));
4409 		parse_security_context(NULL);
4410 		return 0;
4411 	}
4412 
4413 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4414 	if (!newc) {
4415 		yyerror("out of memory");
4416 		return -1;
4417 	}
4418 	memset(newc, 0, sizeof(ocontext_t));
4419 
4420 	newc->u.name = (char *)queue_remove(id_queue);
4421 	if (!newc->u.name) {
4422 		free(newc);
4423 		return -1;
4424 	}
4425 	newc->v.behavior = behavior;
4426 	if (parse_security_context(&newc->context[0])) {
4427 		free(newc->u.name);
4428 		free(newc);
4429 		return -1;
4430 	}
4431 
4432 	head = policydbp->ocontexts[OCON_FSUSE];
4433 
4434 	for (c = head; c; c = c->next) {
4435 		if (!strcmp(newc->u.name, c->u.name)) {
4436 			yyerror2("duplicate fs_use entry for filesystem type %s",
4437 				 newc->u.name);
4438 			context_destroy(&newc->context[0]);
4439 			free(newc->u.name);
4440 			free(newc);
4441 			return -1;
4442 		}
4443 	}
4444 
4445 	newc->next = head;
4446 	policydbp->ocontexts[OCON_FSUSE] = newc;
4447 	return 0;
4448 }
4449 
define_genfs_context_helper(char * fstype,int has_type)4450 int define_genfs_context_helper(char *fstype, int has_type)
4451 {
4452 	struct genfs *genfs_p, *genfs, *newgenfs;
4453 	ocontext_t *newc, *c, *head, *p;
4454 	char *type = NULL;
4455 	int len, len2;
4456 
4457 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4458 		yyerror("genfs not supported for target");
4459 		return -1;
4460 	}
4461 
4462 	if (pass == 1) {
4463 		free(fstype);
4464 		free(queue_remove(id_queue));
4465 		if (has_type)
4466 			free(queue_remove(id_queue));
4467 		parse_security_context(NULL);
4468 		return 0;
4469 	}
4470 
4471 	for (genfs_p = NULL, genfs = policydbp->genfs;
4472 	     genfs; genfs_p = genfs, genfs = genfs->next) {
4473 		if (strcmp(fstype, genfs->fstype) <= 0)
4474 			break;
4475 	}
4476 
4477 	if (!genfs || strcmp(fstype, genfs->fstype)) {
4478 		newgenfs = malloc(sizeof(struct genfs));
4479 		if (!newgenfs) {
4480 			yyerror("out of memory");
4481 			return -1;
4482 		}
4483 		memset(newgenfs, 0, sizeof(struct genfs));
4484 		newgenfs->fstype = fstype;
4485 		newgenfs->next = genfs;
4486 		if (genfs_p)
4487 			genfs_p->next = newgenfs;
4488 		else
4489 			policydbp->genfs = newgenfs;
4490 		genfs = newgenfs;
4491 	}
4492 
4493 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4494 	if (!newc) {
4495 		yyerror("out of memory");
4496 		return -1;
4497 	}
4498 	memset(newc, 0, sizeof(ocontext_t));
4499 
4500 	newc->u.name = (char *)queue_remove(id_queue);
4501 	if (!newc->u.name)
4502 		goto fail;
4503 	if (has_type) {
4504 		type = (char *)queue_remove(id_queue);
4505 		if (!type)
4506 			goto fail;
4507 		if (type[1] != 0) {
4508 			yyerror2("invalid type %s", type);
4509 			goto fail;
4510 		}
4511 		switch (type[0]) {
4512 		case 'b':
4513 			newc->v.sclass = SECCLASS_BLK_FILE;
4514 			break;
4515 		case 'c':
4516 			newc->v.sclass = SECCLASS_CHR_FILE;
4517 			break;
4518 		case 'd':
4519 			newc->v.sclass = SECCLASS_DIR;
4520 			break;
4521 		case 'p':
4522 			newc->v.sclass = SECCLASS_FIFO_FILE;
4523 			break;
4524 		case 'l':
4525 			newc->v.sclass = SECCLASS_LNK_FILE;
4526 			break;
4527 		case 's':
4528 			newc->v.sclass = SECCLASS_SOCK_FILE;
4529 			break;
4530 		case '-':
4531 			newc->v.sclass = SECCLASS_FILE;
4532 			break;
4533 		default:
4534 			yyerror2("invalid type %s", type);
4535 			goto fail;
4536 		}
4537 	}
4538 	if (parse_security_context(&newc->context[0]))
4539 		goto fail;
4540 
4541 	head = genfs->head;
4542 
4543 	for (p = NULL, c = head; c; p = c, c = c->next) {
4544 		if (!strcmp(newc->u.name, c->u.name) &&
4545 		    (!newc->v.sclass || !c->v.sclass
4546 		     || newc->v.sclass == c->v.sclass)) {
4547 			yyerror2("duplicate entry for genfs entry (%s, %s)",
4548 				 fstype, newc->u.name);
4549 			goto fail;
4550 		}
4551 		len = strlen(newc->u.name);
4552 		len2 = strlen(c->u.name);
4553 		if (len > len2)
4554 			break;
4555 	}
4556 
4557 	newc->next = c;
4558 	if (p)
4559 		p->next = newc;
4560 	else
4561 		genfs->head = newc;
4562 	return 0;
4563       fail:
4564 	if (type)
4565 		free(type);
4566 	context_destroy(&newc->context[0]);
4567 	if (fstype)
4568 		free(fstype);
4569 	if (newc->u.name)
4570 		free(newc->u.name);
4571 	free(newc);
4572 	return -1;
4573 }
4574 
define_genfs_context(int has_type)4575 int define_genfs_context(int has_type)
4576 {
4577 	return define_genfs_context_helper(queue_remove(id_queue), has_type);
4578 }
4579 
define_range_trans(int class_specified)4580 int define_range_trans(int class_specified)
4581 {
4582 	char *id;
4583 	level_datum_t *levdatum = 0;
4584 	class_datum_t *cladatum;
4585 	range_trans_rule_t *rule;
4586 	int l, add = 1;
4587 
4588 	if (!mlspol) {
4589 		yyerror("range_transition rule in non-MLS configuration");
4590 		return -1;
4591 	}
4592 
4593 	if (pass == 1) {
4594 		while ((id = queue_remove(id_queue)))
4595 			free(id);
4596 		while ((id = queue_remove(id_queue)))
4597 			free(id);
4598 		if (class_specified)
4599 			while ((id = queue_remove(id_queue)))
4600 				free(id);
4601 		id = queue_remove(id_queue);
4602 		free(id);
4603 		for (l = 0; l < 2; l++) {
4604 			while ((id = queue_remove(id_queue))) {
4605 				free(id);
4606 			}
4607 			id = queue_remove(id_queue);
4608 			if (!id)
4609 				break;
4610 			free(id);
4611 		}
4612 		return 0;
4613 	}
4614 
4615 	rule = malloc(sizeof(struct range_trans_rule));
4616 	if (!rule) {
4617 		yyerror("out of memory");
4618 		return -1;
4619 	}
4620 	range_trans_rule_init(rule);
4621 
4622 	while ((id = queue_remove(id_queue))) {
4623 		if (set_types(&rule->stypes, id, &add, 0))
4624 			goto out;
4625 	}
4626 	add = 1;
4627 	while ((id = queue_remove(id_queue))) {
4628 		if (set_types(&rule->ttypes, id, &add, 0))
4629 			goto out;
4630 	}
4631 
4632 	if (class_specified) {
4633 		if (read_classes(&rule->tclasses))
4634 			goto out;
4635 	} else {
4636 		cladatum = hashtab_search(policydbp->p_classes.table,
4637 		                          "process");
4638 		if (!cladatum) {
4639 			yyerror2("could not find process class for "
4640 			         "legacy range_transition statement");
4641 			goto out;
4642 		}
4643 
4644 		ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
4645 	}
4646 
4647 	id = (char *)queue_remove(id_queue);
4648 	if (!id) {
4649 		yyerror("no range in range_transition definition?");
4650 		goto out;
4651 	}
4652 	for (l = 0; l < 2; l++) {
4653 		levdatum = hashtab_search(policydbp->p_levels.table, id);
4654 		if (!levdatum) {
4655 			yyerror2("unknown level %s used in range_transition "
4656 			         "definition", id);
4657 			free(id);
4658 			goto out;
4659 		}
4660 		free(id);
4661 
4662 		rule->trange.level[l].sens = levdatum->level->sens;
4663 
4664 		while ((id = queue_remove(id_queue))) {
4665 			if (parse_semantic_categories(id, levdatum,
4666 			                          &rule->trange.level[l].cat)) {
4667 				free(id);
4668 				goto out;
4669 			}
4670 			free(id);
4671 		}
4672 
4673 		id = (char *)queue_remove(id_queue);
4674 		if (!id)
4675 			break;
4676 	}
4677 	if (l == 0) {
4678 		if (mls_semantic_level_cpy(&rule->trange.level[1],
4679 		                           &rule->trange.level[0])) {
4680 			yyerror("out of memory");
4681 			goto out;
4682 		}
4683 	}
4684 
4685 	append_range_trans(rule);
4686 	return 0;
4687 
4688 out:
4689 	range_trans_rule_destroy(rule);
4690 	free(rule);
4691 	return -1;
4692 }
4693 
4694 /* FLASK */
4695