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