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