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