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 	uint32_t i;
1525 	int add = 1;
1526 
1527 	avrule = malloc(sizeof(avrule_t));
1528 	if (!avrule) {
1529 		yyerror("out of memory");
1530 		return -1;
1531 	}
1532 	avrule_init(avrule);
1533 	avrule->specified = which;
1534 	avrule->line = policydb_lineno;
1535 	avrule->source_line = source_lineno;
1536 	avrule->source_filename = strdup(source_file);
1537 	if (!avrule->source_filename) {
1538 		yyerror("out of memory");
1539 		return -1;
1540 	}
1541 
1542 	while ((id = queue_remove(id_queue))) {
1543 		if (set_types(&avrule->stypes, id, &add, 0))
1544 			goto bad;
1545 	}
1546 	add = 1;
1547 	while ((id = queue_remove(id_queue))) {
1548 		if (set_types(&avrule->ttypes, id, &add, 0))
1549 			goto bad;
1550 	}
1551 
1552 	ebitmap_init(&tclasses);
1553 	if (read_classes(&tclasses))
1554 		goto bad;
1555 
1556 	id = (char *)queue_remove(id_queue);
1557 	if (!id) {
1558 		yyerror("no newtype?");
1559 		goto bad;
1560 	}
1561 	if (!is_id_in_scope(SYM_TYPES, id)) {
1562 		yyerror2("type %s is not within scope", id);
1563 		free(id);
1564 		goto bad;
1565 	}
1566 	datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1567 						(hashtab_key_t) id);
1568 	if (!datum || datum->flavor == TYPE_ATTRIB) {
1569 		yyerror2("unknown type %s", id);
1570 		goto bad;
1571 	}
1572 
1573 	ebitmap_for_each_bit(&tclasses, node, i) {
1574 		if (ebitmap_node_get_bit(node, i)) {
1575 			perm = malloc(sizeof(class_perm_node_t));
1576 			if (!perm) {
1577 				yyerror("out of memory");
1578 				goto bad;
1579 			}
1580 			class_perm_node_init(perm);
1581 			perm->tclass = i + 1;
1582 			perm->data = datum->s.value;
1583 			perm->next = avrule->perms;
1584 			avrule->perms = perm;
1585 		}
1586 	}
1587 	ebitmap_destroy(&tclasses);
1588 
1589 	*rule = avrule;
1590 	return 0;
1591 
1592       bad:
1593 	avrule_destroy(avrule);
1594 	free(avrule);
1595 	return -1;
1596 }
1597 
define_compute_type(int which)1598 int define_compute_type(int which)
1599 {
1600 	char *id;
1601 	avrule_t *avrule;
1602 
1603 	if (pass == 1) {
1604 		while ((id = queue_remove(id_queue)))
1605 			free(id);
1606 		while ((id = queue_remove(id_queue)))
1607 			free(id);
1608 		while ((id = queue_remove(id_queue)))
1609 			free(id);
1610 		id = queue_remove(id_queue);
1611 		free(id);
1612 		return 0;
1613 	}
1614 
1615 	if (define_compute_type_helper(which, &avrule))
1616 		return -1;
1617 
1618 	append_avrule(avrule);
1619 	return 0;
1620 }
1621 
define_cond_compute_type(int which)1622 avrule_t *define_cond_compute_type(int which)
1623 {
1624 	char *id;
1625 	avrule_t *avrule;
1626 
1627 	if (pass == 1) {
1628 		while ((id = queue_remove(id_queue)))
1629 			free(id);
1630 		while ((id = queue_remove(id_queue)))
1631 			free(id);
1632 		while ((id = queue_remove(id_queue)))
1633 			free(id);
1634 		id = queue_remove(id_queue);
1635 		free(id);
1636 		return (avrule_t *) 1;
1637 	}
1638 
1639 	if (define_compute_type_helper(which, &avrule))
1640 		return COND_ERR;
1641 
1642 	return avrule;
1643 }
1644 
define_bool_tunable(int is_tunable)1645 int define_bool_tunable(int is_tunable)
1646 {
1647 	char *id, *bool_value;
1648 	cond_bool_datum_t *datum;
1649 	int ret;
1650 	uint32_t value;
1651 
1652 	if (pass == 2) {
1653 		while ((id = queue_remove(id_queue)))
1654 			free(id);
1655 		return 0;
1656 	}
1657 
1658 	id = (char *)queue_remove(id_queue);
1659 	if (!id) {
1660 		yyerror("no identifier for bool definition?");
1661 		return -1;
1662 	}
1663 	if (id_has_dot(id)) {
1664 		free(id);
1665 		yyerror("boolean identifiers may not contain periods");
1666 		return -1;
1667 	}
1668 	datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1669 	if (!datum) {
1670 		yyerror("out of memory");
1671 		free(id);
1672 		return -1;
1673 	}
1674 	memset(datum, 0, sizeof(cond_bool_datum_t));
1675 	if (is_tunable)
1676 		datum->flags |= COND_BOOL_FLAGS_TUNABLE;
1677 	ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1678 	switch (ret) {
1679 	case -3:{
1680 			yyerror("Out of memory!");
1681 			goto cleanup;
1682 		}
1683 	case -2:{
1684 			yyerror2("duplicate declaration of boolean %s", id);
1685 			goto cleanup;
1686 		}
1687 	case -1:{
1688 			yyerror("could not declare boolean here");
1689 			goto cleanup;
1690 		}
1691 	case 0:
1692 	case 1:{
1693 			break;
1694 		}
1695 	default:{
1696 			assert(0);	/* should never get here */
1697 		}
1698 	}
1699 	datum->s.value = value;
1700 
1701 	bool_value = (char *)queue_remove(id_queue);
1702 	if (!bool_value) {
1703 		yyerror("no default value for bool definition?");
1704 		free(id);
1705 		return -1;
1706 	}
1707 
1708 	datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
1709 	return 0;
1710       cleanup:
1711 	cond_destroy_bool(id, datum, NULL);
1712 	return -1;
1713 }
1714 
define_cond_pol_list(avrule_t * avlist,avrule_t * sl)1715 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
1716 {
1717 	if (pass == 1) {
1718 		/* return something so we get through pass 1 */
1719 		return (avrule_t *) 1;
1720 	}
1721 
1722 	if (sl == NULL) {
1723 		/* This is a require block, return previous list */
1724 		return avlist;
1725 	}
1726 
1727 	/* prepend the new avlist to the pre-existing one */
1728 	sl->next = avlist;
1729 	return sl;
1730 }
1731 
1732 typedef struct av_ioctl_range {
1733 	uint16_t low;
1734 	uint16_t high;
1735 } av_ioctl_range_t;
1736 
1737 struct av_ioctl_range_list {
1738 	uint8_t omit;
1739 	av_ioctl_range_t range;
1740 	struct av_ioctl_range_list *next;
1741 };
1742 
avrule_sort_ioctls(struct av_ioctl_range_list ** rangehead)1743 int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead)
1744 {
1745 	struct av_ioctl_range_list *r, *r2, *sorted, *sortedhead = NULL;
1746 
1747 	/* order list by range.low */
1748 	for (r = *rangehead; r != NULL; r = r->next) {
1749 		sorted = malloc(sizeof(struct av_ioctl_range_list));
1750 		if (sorted == NULL)
1751 			goto error;
1752 		memcpy(sorted, r, sizeof(struct av_ioctl_range_list));
1753 		sorted->next = NULL;
1754 		if (sortedhead == NULL) {
1755 			sortedhead = sorted;
1756 			continue;
1757 		}
1758 	        for (r2 = sortedhead; r2 != NULL; r2 = r2->next) {
1759 			if (sorted->range.low < r2->range.low) {
1760 				/* range is the new head */
1761 				sorted->next = r2;
1762 				sortedhead = sorted;
1763 				break;
1764 			} else if ((r2 ->next != NULL) &&
1765 					(r->range.low < r2->next->range.low)) {
1766 				/* insert range between elements */
1767 				sorted->next = r2->next;
1768 				r2->next = sorted;
1769 				break;
1770 			} else if (r2->next == NULL) {
1771 				/* range is the new tail*/
1772 				r2->next = sorted;
1773 				break;
1774 			}
1775 		}
1776 	}
1777 
1778 	r = *rangehead;
1779 	while (r != NULL) {
1780 		r2 = r;
1781 		r = r->next;
1782 		free(r2);
1783 	}
1784 	*rangehead = sortedhead;
1785 	return 0;
1786 error:
1787 	yyerror("out of memory");
1788 	return -1;
1789 }
1790 
avrule_merge_ioctls(struct av_ioctl_range_list ** rangehead)1791 int avrule_merge_ioctls(struct av_ioctl_range_list **rangehead)
1792 {
1793 	struct av_ioctl_range_list *r, *tmp;
1794 	r = *rangehead;
1795 	while (r != NULL && r->next != NULL) {
1796 		/* merge */
1797 		if ((r->range.high + 1) >= r->next->range.low) {
1798 			/* keep the higher of the two */
1799 			if (r->range.high < r->next->range.high)
1800 				r->range.high = r->next->range.high;
1801 			tmp = r->next;
1802 			r->next = r->next->next;
1803 			free(tmp);
1804 			continue;
1805 		}
1806 		r = r->next;
1807 	}
1808 	return 0;
1809 }
1810 
avrule_read_ioctls(struct av_ioctl_range_list ** rangehead)1811 int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
1812 {
1813 	char *id;
1814 	struct av_ioctl_range_list *rnew, *r = NULL;
1815 	*rangehead = NULL;
1816 	uint8_t omit = 0;
1817 
1818 	/* read in all the ioctl commands */
1819 	while ((id = queue_remove(id_queue))) {
1820 		if (strcmp(id,"~") == 0) {
1821 			/* these are values to be omitted */
1822 			free(id);
1823 			omit = 1;
1824 		} else if (strcmp(id,"-") == 0) {
1825 			/* high value of range */
1826 			free(id);
1827 			id = queue_remove(id_queue);
1828 			r->range.high = (uint16_t) strtoul(id,NULL,0);
1829 			if (r->range.high < r->range.low) {
1830 				yyerror("Ioctl ranges must be in ascending order.");
1831 				return -1;
1832 			}
1833 			free(id);
1834 		} else {
1835 			/* read in new low value */
1836 			rnew = malloc(sizeof(struct av_ioctl_range_list));
1837 			if (rnew == NULL)
1838 				goto error;
1839 			rnew->next = NULL;
1840 			if (*rangehead == NULL) {
1841 				*rangehead = rnew;
1842 				r = *rangehead;
1843 			} else {
1844 				r->next = rnew;
1845 				r = r->next;
1846 			}
1847 			rnew->range.low = (uint16_t) strtoul(id,NULL,0);
1848 			rnew->range.high = rnew->range.low;
1849 			free(id);
1850 		}
1851 	}
1852 	r = *rangehead;
1853 	r->omit = omit;
1854 	return 0;
1855 error:
1856 	yyerror("out of memory");
1857 	return -1;
1858 }
1859 
1860 /* flip to included ranges */
avrule_omit_ioctls(struct av_ioctl_range_list ** rangehead)1861 int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead)
1862 {
1863 	struct av_ioctl_range_list *rnew, *r, *newhead, *r2;
1864 
1865 	rnew = calloc(1, sizeof(struct av_ioctl_range_list));
1866 	if (!rnew)
1867 		goto error;
1868 
1869 	newhead = rnew;
1870 
1871 	r = *rangehead;
1872 	r2 = newhead;
1873 
1874 	if (r->range.low == 0) {
1875 		r2->range.low = r->range.high + 1;
1876 		r = r->next;
1877 	} else {
1878 		r2->range.low = 0;
1879 	}
1880 
1881 	while (r) {
1882 		r2->range.high = r->range.low - 1;
1883 		rnew = calloc(1, sizeof(struct av_ioctl_range_list));
1884 		if (!rnew)
1885 			goto error;
1886 		r2->next = rnew;
1887 		r2 = r2->next;
1888 
1889 		r2->range.low = r->range.high + 1;
1890 		if (!r->next)
1891 			r2->range.high = 0xffff;
1892 		r = r->next;
1893 	}
1894 
1895 	r = *rangehead;
1896 	while (r != NULL) {
1897 		r2 = r;
1898 		r = r->next;
1899 		free(r2);
1900 	}
1901 	*rangehead = newhead;
1902 	return 0;
1903 
1904 error:
1905 	yyerror("out of memory");
1906 	return -1;
1907 }
1908 
avrule_ioctl_ranges(struct av_ioctl_range_list ** rangelist)1909 int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist)
1910 {
1911 	struct av_ioctl_range_list *rangehead;
1912 	uint8_t omit;
1913 
1914 	/* read in ranges to include and omit */
1915 	if (avrule_read_ioctls(&rangehead))
1916 		return -1;
1917 	omit = rangehead->omit;
1918 	if (rangehead == NULL) {
1919 		yyerror("error processing ioctl commands");
1920 		return -1;
1921 	}
1922 	/* sort and merge the input ioctls */
1923 	if (avrule_sort_ioctls(&rangehead))
1924 		return -1;
1925 	if (avrule_merge_ioctls(&rangehead))
1926 		return -1;
1927 	/* flip ranges if these are ommited*/
1928 	if (omit) {
1929 		if (avrule_omit_ioctls(&rangehead))
1930 			return -1;
1931 	}
1932 
1933 	*rangelist = rangehead;
1934 	return 0;
1935 }
1936 
define_te_avtab_xperms_helper(int which,avrule_t ** rule)1937 int define_te_avtab_xperms_helper(int which, avrule_t ** rule)
1938 {
1939 	char *id;
1940 	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
1941 	class_datum_t *cladatum;
1942 	perm_datum_t *perdatum = NULL;
1943 	ebitmap_t tclasses;
1944 	ebitmap_node_t *node;
1945 	avrule_t *avrule;
1946 	unsigned int i;
1947 	int add = 1, ret = 0;
1948 
1949 	avrule = (avrule_t *) malloc(sizeof(avrule_t));
1950 	if (!avrule) {
1951 		yyerror("out of memory");
1952 		ret = -1;
1953 		goto out;
1954 	}
1955 	avrule_init(avrule);
1956 	avrule->specified = which;
1957 	avrule->line = policydb_lineno;
1958 	avrule->source_line = source_lineno;
1959 	avrule->source_filename = strdup(source_file);
1960 	avrule->xperms = NULL;
1961 	if (!avrule->source_filename) {
1962 		yyerror("out of memory");
1963 		return -1;
1964 	}
1965 
1966 	while ((id = queue_remove(id_queue))) {
1967 		if (set_types
1968 		    (&avrule->stypes, id, &add,
1969 		     which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
1970 			ret = -1;
1971 			goto out;
1972 		}
1973 	}
1974 	add = 1;
1975 	while ((id = queue_remove(id_queue))) {
1976 		if (strcmp(id, "self") == 0) {
1977 			free(id);
1978 			avrule->flags |= RULE_SELF;
1979 			continue;
1980 		}
1981 		if (set_types
1982 		    (&avrule->ttypes, id, &add,
1983 		     which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
1984 			ret = -1;
1985 			goto out;
1986 		}
1987 	}
1988 
1989 	ebitmap_init(&tclasses);
1990 	ret = read_classes(&tclasses);
1991 	if (ret)
1992 		goto out;
1993 
1994 	perms = NULL;
1995 	id = queue_head(id_queue);
1996 	ebitmap_for_each_bit(&tclasses, node, i) {
1997 		if (!ebitmap_node_get_bit(node, i))
1998 			continue;
1999 		cur_perms =
2000 		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2001 		if (!cur_perms) {
2002 			yyerror("out of memory");
2003 			ret = -1;
2004 			goto out;
2005 		}
2006 		class_perm_node_init(cur_perms);
2007 		cur_perms->tclass = i + 1;
2008 		if (!perms)
2009 			perms = cur_perms;
2010 		if (tail)
2011 			tail->next = cur_perms;
2012 		tail = cur_perms;
2013 
2014 		cladatum = policydbp->class_val_to_struct[i];
2015 		perdatum = hashtab_search(cladatum->permissions.table, id);
2016 		if (!perdatum) {
2017 			if (cladatum->comdatum) {
2018 				perdatum = hashtab_search(cladatum->comdatum->
2019 							permissions.table,
2020 							id);
2021 			}
2022 		}
2023 		if (!perdatum) {
2024 			yyerror2("permission %s is not defined"
2025 				     " for class %s", id,
2026 				     policydbp->p_class_val_to_name[i]);
2027 			continue;
2028 		} else if (!is_perm_in_scope (id, policydbp->p_class_val_to_name[i])) {
2029 			yyerror2("permission %s of class %s is"
2030 			     " not within scope", id,
2031 			     policydbp->p_class_val_to_name[i]);
2032 			continue;
2033 		} else {
2034 			cur_perms->data |= 1U << (perdatum->s.value - 1);
2035 		}
2036 	}
2037 
2038 	ebitmap_destroy(&tclasses);
2039 
2040 	avrule->perms = perms;
2041 	*rule = avrule;
2042 
2043 out:
2044 	return ret;
2045 }
2046 
2047 /* index of the u32 containing the permission */
2048 #define XPERM_IDX(x) (x >> 5)
2049 /* set bits 0 through x-1 within the u32 */
2050 #define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
2051 /* low value for this u32 */
2052 #define XPERM_LOW(x) (x << 5)
2053 /* high value for this u32 */
2054 #define XPERM_HIGH(x) (((x + 1) << 5) - 1)
avrule_xperm_setrangebits(uint16_t low,uint16_t high,av_extended_perms_t * xperms)2055 void avrule_xperm_setrangebits(uint16_t low, uint16_t high,
2056 				av_extended_perms_t *xperms)
2057 {
2058 	unsigned int i;
2059 	uint16_t h = high + 1;
2060 	/* for each u32 that this low-high range touches, set driver permissions */
2061 	for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
2062 		/* set all bits in u32 */
2063 		if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
2064 			xperms->perms[i] |= ~0U;
2065 		/* set low bits */
2066 		else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
2067 			xperms->perms[i] |= XPERM_SETBITS(h);
2068 		/* set high bits */
2069 		else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
2070 			xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
2071 		/* set middle bits */
2072 		else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
2073 			xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
2074 	}
2075 }
2076 
avrule_xperms_used(av_extended_perms_t * xperms)2077 int avrule_xperms_used(av_extended_perms_t *xperms)
2078 {
2079 	unsigned int i;
2080 
2081 	for (i = 0; i < sizeof(xperms->perms)/sizeof(xperms->perms[0]); i++) {
2082 		if (xperms->perms[i])
2083 			return 1;
2084 	}
2085 	return 0;
2086 }
2087 
2088 /*
2089  * using definitions found in kernel document ioctl-number.txt
2090  * The kernel components of an ioctl command are:
2091  * dir, size, driver, and fucntion. Only the driver and function fields
2092  * are considered here
2093  */
2094 #define IOC_DRIV(x) (x >> 8)
2095 #define IOC_FUNC(x) (x & 0xff)
2096 #define IOC_CMD(driver, func) ((driver << 8) + func)
avrule_ioctl_partialdriver(struct av_ioctl_range_list * rangelist,av_extended_perms_t * complete_driver,av_extended_perms_t ** extended_perms)2097 int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist,
2098 				av_extended_perms_t *complete_driver,
2099 				av_extended_perms_t **extended_perms)
2100 {
2101 	struct av_ioctl_range_list *r;
2102 	av_extended_perms_t *xperms;
2103 	uint8_t low, high;
2104 
2105 	xperms = calloc(1, sizeof(av_extended_perms_t));
2106 	if (!xperms) {
2107 		yyerror("out of memory");
2108 		return - 1;
2109 	}
2110 
2111 	r = rangelist;
2112 	while(r) {
2113 		low = IOC_DRIV(r->range.low);
2114 		high = IOC_DRIV(r->range.high);
2115 		if (complete_driver) {
2116 			if (!xperm_test(low, complete_driver->perms))
2117 				xperm_set(low, xperms->perms);
2118 			if (!xperm_test(high, complete_driver->perms))
2119 				xperm_set(high, xperms->perms);
2120 		} else {
2121 			xperm_set(low, xperms->perms);
2122 			xperm_set(high, xperms->perms);
2123 		}
2124 		r = r->next;
2125 	}
2126 	if (avrule_xperms_used(xperms)) {
2127 		*extended_perms = xperms;
2128 	} else {
2129 		free(xperms);
2130 		*extended_perms = NULL;
2131 	}
2132 	return 0;
2133 
2134 }
2135 
avrule_ioctl_completedriver(struct av_ioctl_range_list * rangelist,av_extended_perms_t ** extended_perms)2136 int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist,
2137 			av_extended_perms_t **extended_perms)
2138 {
2139 	struct av_ioctl_range_list *r;
2140 	av_extended_perms_t *xperms;
2141 	uint16_t low, high;
2142 	xperms = calloc(1, sizeof(av_extended_perms_t));
2143 	if (!xperms) {
2144 		yyerror("out of memory");
2145 		return - 1;
2146 	}
2147 
2148 	r = rangelist;
2149 	while(r) {
2150 		/*
2151 		 * Any driver code that has sequence 0x00 - 0xff is a complete code,
2152 		 *
2153 		 * if command number = 0xff, then round high up to next code,
2154 		 * else 0x00 - 0xfe keep current code
2155 		 * of this range. temporarily u32 for the + 1
2156 		 * to account for possible rollover before right shift
2157 		 */
2158 		high = IOC_DRIV((uint32_t) (r->range.high + 1));
2159 		/* if 0x00 keep current driver code else 0x01 - 0xff round up to next code*/
2160 		low = IOC_DRIV(r->range.low);
2161 		if (IOC_FUNC(r->range.low))
2162 			low++;
2163 		if (high > low)
2164 			avrule_xperm_setrangebits(low, high - 1, xperms);
2165 		r = r->next;
2166 	}
2167 	if (avrule_xperms_used(xperms)) {
2168 		xperms->driver = 0x00;
2169 		xperms->specified = AVRULE_XPERMS_IOCTLDRIVER;
2170 		*extended_perms = xperms;
2171 	} else {
2172 		free(xperms);
2173 		*extended_perms = NULL;
2174 	}
2175 	return 0;
2176 }
2177 
avrule_ioctl_func(struct av_ioctl_range_list * rangelist,av_extended_perms_t ** extended_perms,unsigned int driver)2178 int avrule_ioctl_func(struct av_ioctl_range_list *rangelist,
2179 		av_extended_perms_t **extended_perms, unsigned int driver)
2180 {
2181 	struct av_ioctl_range_list *r;
2182 	av_extended_perms_t *xperms;
2183 	uint16_t low, high;
2184 
2185 	*extended_perms = NULL;
2186 	xperms = calloc(1, sizeof(av_extended_perms_t));
2187 	if (!xperms) {
2188 		yyerror("out of memory");
2189 		return - 1;
2190 	}
2191 
2192 	r = rangelist;
2193 	/* for the passed in driver code, find the ranges that apply */
2194 	while (r) {
2195 		low = r->range.low;
2196 		high = r->range.high;
2197 		if ((driver != IOC_DRIV(low)) && (driver != IOC_DRIV(high))) {
2198 			r = r->next;
2199 			continue;
2200 		}
2201 
2202 		if (driver == IOC_DRIV(low)) {
2203 			if (high > IOC_CMD(driver, 0xff))
2204 				high = IOC_CMD(driver, 0xff);
2205 
2206 		} else {
2207 			if (low < IOC_CMD(driver, 0))
2208 				low = IOC_CMD(driver, 0);
2209 		}
2210 
2211 		low = IOC_FUNC(low);
2212 		high = IOC_FUNC(high);
2213 		avrule_xperm_setrangebits(low, high, xperms);
2214 		xperms->driver = driver;
2215 		xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION;
2216 		r = r->next;
2217 	}
2218 
2219 	if (avrule_xperms_used(xperms)) {
2220 		*extended_perms = xperms;
2221 	} else {
2222 		free(xperms);
2223 		*extended_perms = NULL;
2224 	}
2225 	return 0;
2226 }
2227 
avrule_ioctl_freeranges(struct av_ioctl_range_list * rangelist)2228 void avrule_ioctl_freeranges(struct av_ioctl_range_list *rangelist)
2229 {
2230 	struct av_ioctl_range_list *r, *tmp;
2231 	r = rangelist;
2232 	while (r) {
2233 		tmp = r;
2234 		r = r->next;
2235 		free(tmp);
2236 	}
2237 }
2238 
xperms_for_each_bit(unsigned int * bit,av_extended_perms_t * xperms)2239 unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms)
2240 {
2241 	unsigned int i;
2242 	for (i = *bit; i < sizeof(xperms->perms)*8; i++) {
2243 		if (xperm_test(i,xperms->perms)) {
2244 			xperm_clear(i, xperms->perms);
2245 			*bit = i;
2246 			return 1;
2247 		}
2248 	}
2249 	return 0;
2250 }
2251 
avrule_cpy(avrule_t * dest,avrule_t * src)2252 int avrule_cpy(avrule_t *dest, avrule_t *src)
2253 {
2254 	class_perm_node_t *src_perms;
2255 	class_perm_node_t *dest_perms, *dest_tail;
2256 	dest_tail = NULL;
2257 
2258 	avrule_init(dest);
2259 	dest->specified = src->specified;
2260 	dest->flags = src->flags;
2261 	if (type_set_cpy(&dest->stypes, &src->stypes)) {
2262 		yyerror("out of memory");
2263 		return - 1;
2264 	}
2265 	if (type_set_cpy(&dest->ttypes, &src->ttypes)) {
2266 		yyerror("out of memory");
2267 		return - 1;
2268 	}
2269 	dest->line = src->line;
2270 	dest->source_filename = strdup(source_file);
2271 	if (!dest->source_filename) {
2272 		yyerror("out of memory");
2273 		return -1;
2274 	}
2275 	dest->source_line = src->source_line;
2276 
2277 	/* increment through the class perms and copy over */
2278 	src_perms = src->perms;
2279 	while (src_perms) {
2280 		dest_perms = (class_perm_node_t *) calloc(1, sizeof(class_perm_node_t));
2281 		class_perm_node_init(dest_perms);
2282 		if (!dest_perms) {
2283 			yyerror("out of memory");
2284 			return -1;
2285 		}
2286 		if (!dest->perms)
2287 			dest->perms = dest_perms;
2288 		else
2289 			dest_tail->next = dest_perms;
2290 
2291 		dest_perms->tclass = src_perms->tclass;
2292 		dest_perms->data = src_perms->data;
2293 		dest_perms->next = NULL;
2294 		dest_tail = dest_perms;
2295 		src_perms = src_perms->next;
2296 	}
2297 	return 0;
2298 }
2299 
define_te_avtab_ioctl(avrule_t * avrule_template)2300 int define_te_avtab_ioctl(avrule_t *avrule_template)
2301 {
2302 	avrule_t *avrule;
2303 	struct av_ioctl_range_list *rangelist;
2304 	av_extended_perms_t *complete_driver, *partial_driver, *xperms;
2305 	unsigned int i;
2306 
2307 
2308 	/* organize ioctl ranges */
2309 	if (avrule_ioctl_ranges(&rangelist))
2310 		return -1;
2311 
2312 	/* create rule for ioctl driver types that are entirely enabled */
2313 	if (avrule_ioctl_completedriver(rangelist, &complete_driver))
2314 		return -1;
2315 	if (complete_driver) {
2316 		avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
2317 		if (!avrule) {
2318 			yyerror("out of memory");
2319 			return -1;
2320 		}
2321 		if (avrule_cpy(avrule, avrule_template))
2322 			return -1;
2323 		avrule->xperms = complete_driver;
2324 		append_avrule(avrule);
2325 	}
2326 
2327 	/* flag ioctl driver codes that are partially enabled */
2328 	if (avrule_ioctl_partialdriver(rangelist, complete_driver, &partial_driver))
2329 		return -1;
2330 
2331 	if (!partial_driver || !avrule_xperms_used(partial_driver))
2332 		goto done;
2333 
2334 	/*
2335 	 * create rule for each partially used driver codes
2336 	 * "partially used" meaning that the code number e.g. socket 0x89
2337 	 * has some permission bits set and others not set.
2338 	 */
2339 	i = 0;
2340 	while (xperms_for_each_bit(&i, partial_driver)) {
2341 		if (avrule_ioctl_func(rangelist, &xperms, i))
2342 			return -1;
2343 
2344 		if (xperms) {
2345 			avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
2346 			if (!avrule) {
2347 				yyerror("out of memory");
2348 				return -1;
2349 			}
2350 			if (avrule_cpy(avrule, avrule_template))
2351 				return -1;
2352 			avrule->xperms = xperms;
2353 			append_avrule(avrule);
2354 		}
2355 	}
2356 
2357 done:
2358 	if (partial_driver)
2359 		free(partial_driver);
2360 
2361 	return 0;
2362 }
2363 
define_te_avtab_extended_perms(int which)2364 int define_te_avtab_extended_perms(int which)
2365 {
2366 	char *id;
2367 	unsigned int i;
2368 	avrule_t *avrule_template;
2369 
2370 	if (pass == 1) {
2371 		for (i = 0; i < 4; i++) {
2372 			while ((id = queue_remove(id_queue)))
2373 				free(id);
2374 		}
2375 		return 0;
2376 	}
2377 
2378 	/* populate avrule template with source/target/tclass */
2379 	if (define_te_avtab_xperms_helper(which, &avrule_template))
2380 		return -1;
2381 
2382 	id = queue_remove(id_queue);
2383 	if (strcmp(id,"ioctl") == 0) {
2384 		if (define_te_avtab_ioctl(avrule_template))
2385 			return -1;
2386 		free(id);
2387 	} else {
2388 		yyerror("only ioctl extended permissions are supported");
2389 		return -1;
2390 	}
2391 	return 0;
2392 }
2393 
define_te_avtab_helper(int which,avrule_t ** rule)2394 int define_te_avtab_helper(int which, avrule_t ** rule)
2395 {
2396 	char *id;
2397 	class_datum_t *cladatum;
2398 	perm_datum_t *perdatum = NULL;
2399 	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
2400 	ebitmap_t tclasses;
2401 	ebitmap_node_t *node;
2402 	avrule_t *avrule;
2403 	unsigned int i;
2404 	int add = 1, ret = 0;
2405 	int suppress = 0;
2406 
2407 	avrule = (avrule_t *) malloc(sizeof(avrule_t));
2408 	if (!avrule) {
2409 		yyerror("memory error");
2410 		ret = -1;
2411 		goto out;
2412 	}
2413 	avrule_init(avrule);
2414 	avrule->specified = which;
2415 	avrule->line = policydb_lineno;
2416 	avrule->source_line = source_lineno;
2417 	avrule->source_filename = strdup(source_file);
2418 	avrule->xperms = NULL;
2419 	if (!avrule->source_filename) {
2420 		yyerror("out of memory");
2421 		return -1;
2422 	}
2423 
2424 
2425 	while ((id = queue_remove(id_queue))) {
2426 		if (set_types
2427 		    (&avrule->stypes, id, &add,
2428 		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
2429 			ret = -1;
2430 			goto out;
2431 		}
2432 	}
2433 	add = 1;
2434 	while ((id = queue_remove(id_queue))) {
2435 		if (strcmp(id, "self") == 0) {
2436 			free(id);
2437 			avrule->flags |= RULE_SELF;
2438 			continue;
2439 		}
2440 		if (set_types
2441 		    (&avrule->ttypes, id, &add,
2442 		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
2443 			ret = -1;
2444 			goto out;
2445 		}
2446 	}
2447 
2448 	ebitmap_init(&tclasses);
2449 	ret = read_classes(&tclasses);
2450 	if (ret)
2451 		goto out;
2452 
2453 	perms = NULL;
2454 	ebitmap_for_each_bit(&tclasses, node, i) {
2455 		if (!ebitmap_node_get_bit(node, i))
2456 			continue;
2457 		cur_perms =
2458 		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2459 		if (!cur_perms) {
2460 			yyerror("out of memory");
2461 			ret = -1;
2462 			goto out;
2463 		}
2464 		class_perm_node_init(cur_perms);
2465 		cur_perms->tclass = i + 1;
2466 		if (!perms)
2467 			perms = cur_perms;
2468 		if (tail)
2469 			tail->next = cur_perms;
2470 		tail = cur_perms;
2471 	}
2472 
2473 	while ((id = queue_remove(id_queue))) {
2474 		cur_perms = perms;
2475 		ebitmap_for_each_bit(&tclasses, node, i) {
2476 			if (!ebitmap_node_get_bit(node, i))
2477 				continue;
2478 			cladatum = policydbp->class_val_to_struct[i];
2479 
2480 			if (strcmp(id, "*") == 0) {
2481 				/* set all permissions in the class */
2482 				cur_perms->data = ~0U;
2483 				goto next;
2484 			}
2485 
2486 			if (strcmp(id, "~") == 0) {
2487 				/* complement the set */
2488 				if (which == AVRULE_DONTAUDIT)
2489 					yywarn("dontaudit rule with a ~?");
2490 				cur_perms->data = ~cur_perms->data;
2491 				goto next;
2492 			}
2493 
2494 			perdatum =
2495 			    hashtab_search(cladatum->permissions.table, id);
2496 			if (!perdatum) {
2497 				if (cladatum->comdatum) {
2498 					perdatum =
2499 					    hashtab_search(cladatum->comdatum->
2500 							   permissions.table,
2501 							   id);
2502 				}
2503 			}
2504 			if (!perdatum) {
2505 				if (!suppress)
2506 					yyerror2("permission %s is not defined"
2507 					     " for class %s", id,
2508 					     policydbp->p_class_val_to_name[i]);
2509 				continue;
2510 			} else
2511 			    if (!is_perm_in_scope
2512 				(id, policydbp->p_class_val_to_name[i])) {
2513 				if (!suppress) {
2514 					yyerror2("permission %s of class %s is"
2515 					     " not within scope", id,
2516 					     policydbp->p_class_val_to_name[i]);
2517 				}
2518 				continue;
2519 			} else {
2520 				cur_perms->data |= 1U << (perdatum->s.value - 1);
2521 			}
2522 		      next:
2523 			cur_perms = cur_perms->next;
2524 		}
2525 
2526 		free(id);
2527 	}
2528 
2529 	ebitmap_destroy(&tclasses);
2530 
2531 	avrule->perms = perms;
2532 	*rule = avrule;
2533 
2534       out:
2535 	return ret;
2536 
2537 }
2538 
define_cond_te_avtab(int which)2539 avrule_t *define_cond_te_avtab(int which)
2540 {
2541 	char *id;
2542 	avrule_t *avrule;
2543 	int i;
2544 
2545 	if (pass == 1) {
2546 		for (i = 0; i < 4; i++) {
2547 			while ((id = queue_remove(id_queue)))
2548 				free(id);
2549 		}
2550 		return (avrule_t *) 1;	/* any non-NULL value */
2551 	}
2552 
2553 	if (define_te_avtab_helper(which, &avrule))
2554 		return COND_ERR;
2555 
2556 	return avrule;
2557 }
2558 
define_te_avtab(int which)2559 int define_te_avtab(int which)
2560 {
2561 	char *id;
2562 	avrule_t *avrule;
2563 	int i;
2564 
2565 	if (pass == 1) {
2566 		for (i = 0; i < 4; i++) {
2567 			while ((id = queue_remove(id_queue)))
2568 				free(id);
2569 		}
2570 		return 0;
2571 	}
2572 
2573 	if (define_te_avtab_helper(which, &avrule))
2574 		return -1;
2575 
2576 	/* append this avrule to the end of the current rules list */
2577 	append_avrule(avrule);
2578 	return 0;
2579 }
2580 
2581 /* The role-types rule is no longer used to declare regular role or
2582  * role attribute, but solely aimed for declaring role-types associations.
2583  */
define_role_types(void)2584 int define_role_types(void)
2585 {
2586 	role_datum_t *role;
2587 	char *id;
2588 	int add = 1;
2589 
2590 	if (pass == 1) {
2591 		while ((id = queue_remove(id_queue)))
2592 			free(id);
2593 		return 0;
2594 	}
2595 
2596 	id = (char *)queue_remove(id_queue);
2597 	if (!id) {
2598 		yyerror("no role name for role-types rule?");
2599 		return -1;
2600 	}
2601 
2602 	if (!is_id_in_scope(SYM_ROLES, id)) {
2603 		yyerror2("role %s is not within scope", id);
2604 		free(id);
2605 		return -1;
2606 	}
2607 
2608 	role = hashtab_search(policydbp->p_roles.table, id);
2609 	if (!role) {
2610 		yyerror2("unknown role %s", id);
2611 		free(id);
2612 		return -1;
2613 	}
2614 
2615 	while ((id = queue_remove(id_queue))) {
2616 		if (set_types(&role->types, id, &add, 0))
2617 			return -1;
2618 	}
2619 
2620 	return 0;
2621 }
2622 
define_attrib_role(void)2623 int define_attrib_role(void)
2624 {
2625 	if (pass == 2) {
2626 		free(queue_remove(id_queue));
2627 		return 0;
2628 	}
2629 
2630 	/* Declare a role attribute */
2631 	if (declare_role(TRUE) == NULL)
2632 		return -1;
2633 
2634 	return 0;
2635 }
2636 
define_role_attr(void)2637 int define_role_attr(void)
2638 {
2639 	char *id;
2640 	role_datum_t *r, *attr;
2641 
2642 	if (pass == 2) {
2643 		while ((id = queue_remove(id_queue)))
2644 			free(id);
2645 		return 0;
2646 	}
2647 
2648 	/* Declare a regular role */
2649 	if ((r = declare_role(FALSE)) == NULL)
2650 		return -1;
2651 
2652 	while ((id = queue_remove(id_queue))) {
2653 		if (!is_id_in_scope(SYM_ROLES, id)) {
2654 			yyerror2("attribute %s is not within scope", id);
2655 			free(id);
2656 			return -1;
2657 		}
2658 		attr = hashtab_search(policydbp->p_roles.table, id);
2659 		if (!attr) {
2660 			/* treat it as a fatal error */
2661 			yyerror2("role attribute %s is not declared", id);
2662 			free(id);
2663 			return -1;
2664 		}
2665 
2666 		if (attr->flavor != ROLE_ATTRIB) {
2667 			yyerror2("%s is a regular role, not an attribute", id);
2668 			free(id);
2669 			return -1;
2670 		}
2671 
2672 		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2673 			yyerror("Out of memory!");
2674 			return -1;
2675 		}
2676 
2677 		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2678 			yyerror("out of memory");
2679 			return -1;
2680 		}
2681 	}
2682 
2683 	return 0;
2684 }
2685 
define_roleattribute(void)2686 int define_roleattribute(void)
2687 {
2688 	char *id;
2689 	role_datum_t *r, *attr;
2690 
2691 	if (pass == 2) {
2692 		while ((id = queue_remove(id_queue)))
2693 			free(id);
2694 		return 0;
2695 	}
2696 
2697 	id = (char *)queue_remove(id_queue);
2698 	if (!id) {
2699 		yyerror("no role name for roleattribute definition?");
2700 		return -1;
2701 	}
2702 
2703 	if (!is_id_in_scope(SYM_ROLES, id)) {
2704 		yyerror2("role %s is not within scope", id);
2705 		free(id);
2706 		return -1;
2707 	}
2708 	r = hashtab_search(policydbp->p_roles.table, id);
2709 	/* We support adding one role attribute into another */
2710 	if (!r) {
2711 		yyerror2("unknown role %s", id);
2712 		free(id);
2713 		return -1;
2714 	}
2715 
2716 	while ((id = queue_remove(id_queue))) {
2717 		if (!is_id_in_scope(SYM_ROLES, id)) {
2718 			yyerror2("attribute %s is not within scope", id);
2719 			free(id);
2720 			return -1;
2721 		}
2722 		attr = hashtab_search(policydbp->p_roles.table, id);
2723 		if (!attr) {
2724 			/* treat it as a fatal error */
2725 			yyerror2("role attribute %s is not declared", id);
2726 			free(id);
2727 			return -1;
2728 		}
2729 
2730 		if (attr->flavor != ROLE_ATTRIB) {
2731 			yyerror2("%s is a regular role, not an attribute", id);
2732 			free(id);
2733 			return -1;
2734 		}
2735 
2736 		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2737 			yyerror("Out of memory!");
2738 			return -1;
2739 		}
2740 
2741 		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2742 			yyerror("out of memory");
2743 			return -1;
2744 		}
2745 	}
2746 
2747 	return 0;
2748 }
2749 
merge_roles_dom(role_datum_t * r1,role_datum_t * r2)2750 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
2751 {
2752 	role_datum_t *new;
2753 
2754 	if (pass == 1) {
2755 		return (role_datum_t *) 1;	/* any non-NULL value */
2756 	}
2757 
2758 	new = malloc(sizeof(role_datum_t));
2759 	if (!new) {
2760 		yyerror("out of memory");
2761 		return NULL;
2762 	}
2763 	memset(new, 0, sizeof(role_datum_t));
2764 	new->s.value = 0;		/* temporary role */
2765 	if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
2766 		yyerror("out of memory");
2767 		free(new);
2768 		return NULL;
2769 	}
2770 	if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
2771 		yyerror("out of memory");
2772 		free(new);
2773 		return NULL;
2774 	}
2775 	if (!r1->s.value) {
2776 		/* free intermediate result */
2777 		type_set_destroy(&r1->types);
2778 		ebitmap_destroy(&r1->dominates);
2779 		free(r1);
2780 	}
2781 	if (!r2->s.value) {
2782 		/* free intermediate result */
2783 		yyerror("right hand role is temporary?");
2784 		type_set_destroy(&r2->types);
2785 		ebitmap_destroy(&r2->dominates);
2786 		free(r2);
2787 	}
2788 	return new;
2789 }
2790 
2791 /* This function eliminates the ordering dependency of role dominance rule */
dominate_role_recheck(hashtab_key_t key,hashtab_datum_t datum,void * arg)2792 static int dominate_role_recheck(hashtab_key_t key __attribute__ ((unused)),
2793 				 hashtab_datum_t datum, void *arg)
2794 {
2795 	role_datum_t *rdp = (role_datum_t *) arg;
2796 	role_datum_t *rdatum = (role_datum_t *) datum;
2797 	ebitmap_node_t *node;
2798 	uint32_t i;
2799 
2800 	/* Don't bother to process against self role */
2801 	if (rdatum->s.value == rdp->s.value)
2802 		return 0;
2803 
2804 	/* If a dominating role found */
2805 	if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
2806 		ebitmap_t types;
2807 		ebitmap_init(&types);
2808 		if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
2809 			ebitmap_destroy(&types);
2810 			return -1;
2811 		}
2812 		/* raise types and dominates from dominated role */
2813 		ebitmap_for_each_bit(&rdp->dominates, node, i) {
2814 			if (ebitmap_node_get_bit(node, i))
2815 				if (ebitmap_set_bit
2816 				    (&rdatum->dominates, i, TRUE))
2817 					goto oom;
2818 		}
2819 		ebitmap_for_each_bit(&types, node, i) {
2820 			if (ebitmap_node_get_bit(node, i))
2821 				if (ebitmap_set_bit
2822 				    (&rdatum->types.types, i, TRUE))
2823 					goto oom;
2824 		}
2825 		ebitmap_destroy(&types);
2826 	}
2827 
2828 	/* go through all the roles */
2829 	return 0;
2830       oom:
2831 	yyerror("Out of memory");
2832 	return -1;
2833 }
2834 
define_role_dom(role_datum_t * r)2835 role_datum_t *define_role_dom(role_datum_t * r)
2836 {
2837 	role_datum_t *role;
2838 	char *role_id;
2839 	ebitmap_node_t *node;
2840 	unsigned int i;
2841 	int ret;
2842 
2843 	if (pass == 1) {
2844 		role_id = queue_remove(id_queue);
2845 		free(role_id);
2846 		return (role_datum_t *) 1;	/* any non-NULL value */
2847 	}
2848 
2849 	yywarn("Role dominance has been deprecated");
2850 
2851 	role_id = queue_remove(id_queue);
2852 	if (!is_id_in_scope(SYM_ROLES, role_id)) {
2853 		yyerror2("role %s is not within scope", role_id);
2854 		free(role_id);
2855 		return NULL;
2856 	}
2857 	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2858 					       role_id);
2859 	if (!role) {
2860 		role = (role_datum_t *) malloc(sizeof(role_datum_t));
2861 		if (!role) {
2862 			yyerror("out of memory");
2863 			free(role_id);
2864 			return NULL;
2865 		}
2866 		memset(role, 0, sizeof(role_datum_t));
2867 		ret =
2868 		    declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
2869 				   (hashtab_datum_t) role, &role->s.value,
2870 				   &role->s.value);
2871 		switch (ret) {
2872 		case -3:{
2873 				yyerror("Out of memory!");
2874 				goto cleanup;
2875 			}
2876 		case -2:{
2877 				yyerror2("duplicate declaration of role %s",
2878 					 role_id);
2879 				goto cleanup;
2880 			}
2881 		case -1:{
2882 				yyerror("could not declare role here");
2883 				goto cleanup;
2884 			}
2885 		case 0:
2886 		case 1:{
2887 				break;
2888 			}
2889 		default:{
2890 				assert(0);	/* should never get here */
2891 			}
2892 		}
2893 		if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
2894 			yyerror("Out of memory!");
2895 			goto cleanup;
2896 		}
2897 	}
2898 	if (r) {
2899 		ebitmap_t types;
2900 		ebitmap_init(&types);
2901 		ebitmap_for_each_bit(&r->dominates, node, i) {
2902 			if (ebitmap_node_get_bit(node, i))
2903 				if (ebitmap_set_bit(&role->dominates, i, TRUE))
2904 					goto oom;
2905 		}
2906 		if (type_set_expand(&r->types, &types, policydbp, 1)) {
2907 			ebitmap_destroy(&types);
2908 			return NULL;
2909 		}
2910 		ebitmap_for_each_bit(&types, node, i) {
2911 			if (ebitmap_node_get_bit(node, i))
2912 				if (ebitmap_set_bit
2913 				    (&role->types.types, i, TRUE))
2914 					goto oom;
2915 		}
2916 		ebitmap_destroy(&types);
2917 		if (!r->s.value) {
2918 			/* free intermediate result */
2919 			type_set_destroy(&r->types);
2920 			ebitmap_destroy(&r->dominates);
2921 			free(r);
2922 		}
2923 		/*
2924 		 * Now go through all the roles and escalate this role's
2925 		 * dominates and types if a role dominates this role.
2926 		 */
2927 		hashtab_map(policydbp->p_roles.table,
2928 			    dominate_role_recheck, role);
2929 	}
2930 	return role;
2931       cleanup:
2932 	free(role_id);
2933 	role_datum_destroy(role);
2934 	free(role);
2935 	return NULL;
2936       oom:
2937 	yyerror("Out of memory");
2938 	goto cleanup;
2939 }
2940 
role_val_to_name_helper(hashtab_key_t key,hashtab_datum_t datum,void * p)2941 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
2942 				   void *p)
2943 {
2944 	struct val_to_name *v = p;
2945 	role_datum_t *roldatum;
2946 
2947 	roldatum = (role_datum_t *) datum;
2948 
2949 	if (v->val == roldatum->s.value) {
2950 		v->name = key;
2951 		return 1;
2952 	}
2953 
2954 	return 0;
2955 }
2956 
role_val_to_name(unsigned int val)2957 static char *role_val_to_name(unsigned int val)
2958 {
2959 	struct val_to_name v;
2960 	int rc;
2961 
2962 	v.val = val;
2963 	rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2964 	if (rc)
2965 		return v.name;
2966 	return NULL;
2967 }
2968 
set_roles(role_set_t * set,char * id)2969 static int set_roles(role_set_t * set, char *id)
2970 {
2971 	role_datum_t *r;
2972 
2973 	if (strcmp(id, "*") == 0) {
2974 		free(id);
2975 		yyerror("* is not allowed for role sets");
2976 		return -1;
2977 	}
2978 
2979 	if (strcmp(id, "~") == 0) {
2980 		free(id);
2981 		yyerror("~ is not allowed for role sets");
2982 		return -1;
2983 	}
2984 	if (!is_id_in_scope(SYM_ROLES, id)) {
2985 		yyerror2("role %s is not within scope", id);
2986 		free(id);
2987 		return -1;
2988 	}
2989 	r = hashtab_search(policydbp->p_roles.table, id);
2990 	if (!r) {
2991 		yyerror2("unknown role %s", id);
2992 		free(id);
2993 		return -1;
2994 	}
2995 
2996 	if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
2997 		yyerror("out of memory");
2998 		free(id);
2999 		return -1;
3000 	}
3001 	free(id);
3002 	return 0;
3003 }
3004 
define_role_trans(int class_specified)3005 int define_role_trans(int class_specified)
3006 {
3007 	char *id;
3008 	role_datum_t *role;
3009 	role_set_t roles;
3010 	type_set_t types;
3011 	class_datum_t *cladatum;
3012 	ebitmap_t e_types, e_roles, e_classes;
3013 	ebitmap_node_t *tnode, *rnode, *cnode;
3014 	struct role_trans *tr = NULL;
3015 	struct role_trans_rule *rule = NULL;
3016 	unsigned int i, j, k;
3017 	int add = 1;
3018 
3019 	if (pass == 1) {
3020 		while ((id = queue_remove(id_queue)))
3021 			free(id);
3022 		while ((id = queue_remove(id_queue)))
3023 			free(id);
3024 		if (class_specified)
3025 			while ((id = queue_remove(id_queue)))
3026 				free(id);
3027 		id = queue_remove(id_queue);
3028 		free(id);
3029 		return 0;
3030 	}
3031 
3032 	role_set_init(&roles);
3033 	ebitmap_init(&e_roles);
3034 	type_set_init(&types);
3035 	ebitmap_init(&e_types);
3036 	ebitmap_init(&e_classes);
3037 
3038 	while ((id = queue_remove(id_queue))) {
3039 		if (set_roles(&roles, id))
3040 			return -1;
3041 	}
3042 	add = 1;
3043 	while ((id = queue_remove(id_queue))) {
3044 		if (set_types(&types, id, &add, 0))
3045 			return -1;
3046 	}
3047 
3048 	if (class_specified) {
3049 		if (read_classes(&e_classes))
3050 			return -1;
3051 	} else {
3052 		cladatum = hashtab_search(policydbp->p_classes.table,
3053 					  "process");
3054 		if (!cladatum) {
3055 			yyerror2("could not find process class for "
3056 				 "legacy role_transition statement");
3057 			return -1;
3058 		}
3059 
3060 		if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) {
3061 			yyerror("out of memory");
3062 			return -1;
3063 		}
3064 	}
3065 
3066 	id = (char *)queue_remove(id_queue);
3067 	if (!id) {
3068 		yyerror("no new role in transition definition?");
3069 		goto bad;
3070 	}
3071 	if (!is_id_in_scope(SYM_ROLES, id)) {
3072 		yyerror2("role %s is not within scope", id);
3073 		free(id);
3074 		goto bad;
3075 	}
3076 	role = hashtab_search(policydbp->p_roles.table, id);
3077 	if (!role) {
3078 		yyerror2("unknown role %s used in transition definition", id);
3079 		goto bad;
3080 	}
3081 
3082 	if (role->flavor != ROLE_ROLE) {
3083 		yyerror2("the new role %s must be a regular role", id);
3084 		goto bad;
3085 	}
3086 
3087 	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
3088 	if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
3089 		goto bad;
3090 
3091 	if (type_set_expand(&types, &e_types, policydbp, 1))
3092 		goto bad;
3093 
3094 	ebitmap_for_each_bit(&e_roles, rnode, i) {
3095 		if (!ebitmap_node_get_bit(rnode, i))
3096 			continue;
3097 		ebitmap_for_each_bit(&e_types, tnode, j) {
3098 			if (!ebitmap_node_get_bit(tnode, j))
3099 				continue;
3100 			ebitmap_for_each_bit(&e_classes, cnode, k) {
3101 				if (!ebitmap_node_get_bit(cnode, k))
3102 					continue;
3103 				for (tr = policydbp->role_tr; tr;
3104 				     tr = tr->next) {
3105 					if (tr->role == (i + 1) &&
3106 					    tr->type == (j + 1) &&
3107 					    tr->tclass == (k + 1)) {
3108 						yyerror2("duplicate role "
3109 							 "transition for "
3110 							 "(%s,%s,%s)",
3111 							 role_val_to_name(i+1),
3112 							 policydbp->p_type_val_to_name[j],
3113 							 policydbp->p_class_val_to_name[k]);
3114 						goto bad;
3115 					}
3116 				}
3117 
3118 				tr = malloc(sizeof(struct role_trans));
3119 				if (!tr) {
3120 					yyerror("out of memory");
3121 					return -1;
3122 				}
3123 				memset(tr, 0, sizeof(struct role_trans));
3124 				tr->role = i + 1;
3125 				tr->type = j + 1;
3126 				tr->tclass = k + 1;
3127 				tr->new_role = role->s.value;
3128 				tr->next = policydbp->role_tr;
3129 				policydbp->role_tr = tr;
3130 			}
3131 		}
3132 	}
3133 	/* Now add the real rule */
3134 	rule = malloc(sizeof(struct role_trans_rule));
3135 	if (!rule) {
3136 		yyerror("out of memory");
3137 		return -1;
3138 	}
3139 	memset(rule, 0, sizeof(struct role_trans_rule));
3140 	rule->roles = roles;
3141 	rule->types = types;
3142 	rule->classes = e_classes;
3143 	rule->new_role = role->s.value;
3144 
3145 	append_role_trans(rule);
3146 
3147 	ebitmap_destroy(&e_roles);
3148 	ebitmap_destroy(&e_types);
3149 
3150 	return 0;
3151 
3152       bad:
3153 	return -1;
3154 }
3155 
define_role_allow(void)3156 int define_role_allow(void)
3157 {
3158 	char *id;
3159 	struct role_allow_rule *ra = 0;
3160 
3161 	if (pass == 1) {
3162 		while ((id = queue_remove(id_queue)))
3163 			free(id);
3164 		while ((id = queue_remove(id_queue)))
3165 			free(id);
3166 		return 0;
3167 	}
3168 
3169 	ra = malloc(sizeof(role_allow_rule_t));
3170 	if (!ra) {
3171 		yyerror("out of memory");
3172 		return -1;
3173 	}
3174 	role_allow_rule_init(ra);
3175 
3176 	while ((id = queue_remove(id_queue))) {
3177 		if (set_roles(&ra->roles, id)) {
3178 			free(ra);
3179 			return -1;
3180 		}
3181 	}
3182 
3183 	while ((id = queue_remove(id_queue))) {
3184 		if (set_roles(&ra->new_roles, id)) {
3185 			free(ra);
3186 			return -1;
3187 		}
3188 	}
3189 
3190 	append_role_allow(ra);
3191 	return 0;
3192 }
3193 
define_cond_filename_trans(void)3194 avrule_t *define_cond_filename_trans(void)
3195 {
3196 	yyerror("type transitions with a filename not allowed inside "
3197 		"conditionals\n");
3198 	return COND_ERR;
3199 }
3200 
define_filename_trans(void)3201 int define_filename_trans(void)
3202 {
3203 	char *id, *name = NULL;
3204 	type_set_t stypes, ttypes;
3205 	ebitmap_t e_stypes, e_ttypes;
3206 	ebitmap_t e_tclasses;
3207 	ebitmap_node_t *snode, *tnode, *cnode;
3208 	filename_trans_t *ft;
3209 	filename_trans_rule_t *ftr;
3210 	type_datum_t *typdatum;
3211 	uint32_t otype;
3212 	unsigned int c, s, t;
3213 	int add;
3214 
3215 	if (pass == 1) {
3216 		/* stype */
3217 		while ((id = queue_remove(id_queue)))
3218 			free(id);
3219 		/* ttype */
3220 		while ((id = queue_remove(id_queue)))
3221 			free(id);
3222 		/* tclass */
3223 		while ((id = queue_remove(id_queue)))
3224 			free(id);
3225 		/* otype */
3226 		id = queue_remove(id_queue);
3227 		free(id);
3228 		/* name */
3229 		id = queue_remove(id_queue);
3230 		free(id);
3231 		return 0;
3232 	}
3233 
3234 
3235 	add = 1;
3236 	type_set_init(&stypes);
3237 	while ((id = queue_remove(id_queue))) {
3238 		if (set_types(&stypes, id, &add, 0))
3239 			goto bad;
3240 	}
3241 
3242 	add =1;
3243 	type_set_init(&ttypes);
3244 	while ((id = queue_remove(id_queue))) {
3245 		if (set_types(&ttypes, id, &add, 0))
3246 			goto bad;
3247 	}
3248 
3249 	ebitmap_init(&e_tclasses);
3250 	if (read_classes(&e_tclasses))
3251 		goto bad;
3252 
3253 	id = (char *)queue_remove(id_queue);
3254 	if (!id) {
3255 		yyerror("no otype in transition definition?");
3256 		goto bad;
3257 	}
3258 	if (!is_id_in_scope(SYM_TYPES, id)) {
3259 		yyerror2("type %s is not within scope", id);
3260 		free(id);
3261 		goto bad;
3262 	}
3263 	typdatum = hashtab_search(policydbp->p_types.table, id);
3264 	if (!typdatum) {
3265 		yyerror2("unknown type %s used in transition definition", id);
3266 		goto bad;
3267 	}
3268 	free(id);
3269 	otype = typdatum->s.value;
3270 
3271 	name = queue_remove(id_queue);
3272 	if (!name) {
3273 		yyerror("no pathname specified in filename_trans definition?");
3274 		goto bad;
3275 	}
3276 
3277 	/* We expand the class set into seperate rules.  We expand the types
3278 	 * just to make sure there are not duplicates.  They will get turned
3279 	 * into seperate rules later */
3280 	ebitmap_init(&e_stypes);
3281 	if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
3282 		goto bad;
3283 
3284 	ebitmap_init(&e_ttypes);
3285 	if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
3286 		goto bad;
3287 
3288 	ebitmap_for_each_bit(&e_tclasses, cnode, c) {
3289 		if (!ebitmap_node_get_bit(cnode, c))
3290 			continue;
3291 		ebitmap_for_each_bit(&e_stypes, snode, s) {
3292 			if (!ebitmap_node_get_bit(snode, s))
3293 				continue;
3294 			ebitmap_for_each_bit(&e_ttypes, tnode, t) {
3295 				if (!ebitmap_node_get_bit(tnode, t))
3296 					continue;
3297 
3298 				for (ft = policydbp->filename_trans; ft; ft = ft->next) {
3299 					if (ft->stype == (s + 1) &&
3300 					    ft->ttype == (t + 1) &&
3301 					    ft->tclass == (c + 1) &&
3302 					    !strcmp(ft->name, name)) {
3303 						yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
3304 							 name,
3305 							 policydbp->p_type_val_to_name[s],
3306 							 policydbp->p_type_val_to_name[t],
3307 							 policydbp->p_class_val_to_name[c]);
3308 						goto bad;
3309 					}
3310 				}
3311 
3312 				ft = malloc(sizeof(*ft));
3313 				if (!ft) {
3314 					yyerror("out of memory");
3315 					goto bad;
3316 				}
3317 				memset(ft, 0, sizeof(*ft));
3318 
3319 				ft->next = policydbp->filename_trans;
3320 				policydbp->filename_trans = ft;
3321 
3322 				ft->name = strdup(name);
3323 				if (!ft->name) {
3324 					yyerror("out of memory");
3325 					goto bad;
3326 				}
3327 				ft->stype = s + 1;
3328 				ft->ttype = t + 1;
3329 				ft->tclass = c + 1;
3330 				ft->otype = otype;
3331 			}
3332 		}
3333 
3334 		/* Now add the real rule since we didn't find any duplicates */
3335 		ftr = malloc(sizeof(*ftr));
3336 		if (!ftr) {
3337 			yyerror("out of memory");
3338 			goto bad;
3339 		}
3340 		filename_trans_rule_init(ftr);
3341 		append_filename_trans(ftr);
3342 
3343 		ftr->name = strdup(name);
3344 		if (type_set_cpy(&ftr->stypes, &stypes)) {
3345 			yyerror("out of memory");
3346 			goto bad;
3347 		}
3348 		if (type_set_cpy(&ftr->ttypes, &ttypes)) {
3349 			yyerror("out of memory");
3350 			goto bad;
3351 		}
3352 		ftr->tclass = c + 1;
3353 		ftr->otype = otype;
3354 	}
3355 
3356 	free(name);
3357 	ebitmap_destroy(&e_stypes);
3358 	ebitmap_destroy(&e_ttypes);
3359 	ebitmap_destroy(&e_tclasses);
3360 
3361 	return 0;
3362 
3363 bad:
3364 	free(name);
3365 	return -1;
3366 }
3367 
constraint_expr_clone(constraint_expr_t * expr)3368 static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
3369 {
3370 	constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
3371 	for (e = expr; e; e = e->next) {
3372 		newe = malloc(sizeof(*newe));
3373 		if (!newe)
3374 			goto oom;
3375 		if (constraint_expr_init(newe) == -1) {
3376 			free(newe);
3377 			goto oom;
3378 		}
3379 		if (l)
3380 			l->next = newe;
3381 		else
3382 			h = newe;
3383 		l = newe;
3384 		newe->expr_type = e->expr_type;
3385 		newe->attr = e->attr;
3386 		newe->op = e->op;
3387 		if (newe->expr_type == CEXPR_NAMES) {
3388 			if (newe->attr & CEXPR_TYPE) {
3389 				if (type_set_cpy
3390 				    (newe->type_names, e->type_names))
3391 					goto oom;
3392 			} else {
3393 				if (ebitmap_cpy(&newe->names, &e->names))
3394 					goto oom;
3395 			}
3396 		}
3397 	}
3398 
3399 	return h;
3400       oom:
3401 	e = h;
3402 	while (e) {
3403 		l = e;
3404 		e = e->next;
3405 		constraint_expr_destroy(l);
3406 	}
3407 	return NULL;
3408 }
3409 
define_constraint(constraint_expr_t * expr)3410 int define_constraint(constraint_expr_t * expr)
3411 {
3412 	struct constraint_node *node;
3413 	char *id;
3414 	class_datum_t *cladatum;
3415 	perm_datum_t *perdatum;
3416 	ebitmap_t classmap;
3417 	ebitmap_node_t *enode;
3418 	constraint_expr_t *e;
3419 	unsigned int i;
3420 	int depth;
3421 	unsigned char useexpr = 1;
3422 
3423 	if (pass == 1) {
3424 		while ((id = queue_remove(id_queue)))
3425 			free(id);
3426 		while ((id = queue_remove(id_queue)))
3427 			free(id);
3428 		return 0;
3429 	}
3430 
3431 	depth = -1;
3432 	for (e = expr; e; e = e->next) {
3433 		switch (e->expr_type) {
3434 		case CEXPR_NOT:
3435 			if (depth < 0) {
3436 				yyerror("illegal constraint expression");
3437 				return -1;
3438 			}
3439 			break;
3440 		case CEXPR_AND:
3441 		case CEXPR_OR:
3442 			if (depth < 1) {
3443 				yyerror("illegal constraint expression");
3444 				return -1;
3445 			}
3446 			depth--;
3447 			break;
3448 		case CEXPR_ATTR:
3449 		case CEXPR_NAMES:
3450 			if (e->attr & CEXPR_XTARGET) {
3451 				yyerror("illegal constraint expression");
3452 				return -1;	/* only for validatetrans rules */
3453 			}
3454 			if (depth == (CEXPR_MAXDEPTH - 1)) {
3455 				yyerror("constraint expression is too deep");
3456 				return -1;
3457 			}
3458 			depth++;
3459 			break;
3460 		default:
3461 			yyerror("illegal constraint expression");
3462 			return -1;
3463 		}
3464 	}
3465 	if (depth != 0) {
3466 		yyerror("illegal constraint expression");
3467 		return -1;
3468 	}
3469 
3470 	ebitmap_init(&classmap);
3471 	while ((id = queue_remove(id_queue))) {
3472 		if (!is_id_in_scope(SYM_CLASSES, id)) {
3473 			yyerror2("class %s is not within scope", id);
3474 			free(id);
3475 			return -1;
3476 		}
3477 		cladatum =
3478 		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3479 						     (hashtab_key_t) id);
3480 		if (!cladatum) {
3481 			yyerror2("class %s is not defined", id);
3482 			ebitmap_destroy(&classmap);
3483 			free(id);
3484 			return -1;
3485 		}
3486 		if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
3487 			yyerror("out of memory");
3488 			ebitmap_destroy(&classmap);
3489 			free(id);
3490 			return -1;
3491 		}
3492 		node = malloc(sizeof(struct constraint_node));
3493 		if (!node) {
3494 			yyerror("out of memory");
3495 			free(node);
3496 			return -1;
3497 		}
3498 		memset(node, 0, sizeof(constraint_node_t));
3499 		if (useexpr) {
3500 			node->expr = expr;
3501 			useexpr = 0;
3502 		} else {
3503 			node->expr = constraint_expr_clone(expr);
3504 		}
3505 		if (!node->expr) {
3506 			yyerror("out of memory");
3507 			free(node);
3508 			return -1;
3509 		}
3510 		node->permissions = 0;
3511 
3512 		node->next = cladatum->constraints;
3513 		cladatum->constraints = node;
3514 
3515 		free(id);
3516 	}
3517 
3518 	while ((id = queue_remove(id_queue))) {
3519 		ebitmap_for_each_bit(&classmap, enode, i) {
3520 			if (ebitmap_node_get_bit(enode, i)) {
3521 				cladatum = policydbp->class_val_to_struct[i];
3522 				node = cladatum->constraints;
3523 
3524 				perdatum =
3525 				    (perm_datum_t *) hashtab_search(cladatum->
3526 								    permissions.
3527 								    table,
3528 								    (hashtab_key_t)
3529 								    id);
3530 				if (!perdatum) {
3531 					if (cladatum->comdatum) {
3532 						perdatum =
3533 						    (perm_datum_t *)
3534 						    hashtab_search(cladatum->
3535 								   comdatum->
3536 								   permissions.
3537 								   table,
3538 								   (hashtab_key_t)
3539 								   id);
3540 					}
3541 					if (!perdatum) {
3542 						yyerror2("permission %s is not"
3543 							 " defined", id);
3544 						free(id);
3545 						ebitmap_destroy(&classmap);
3546 						return -1;
3547 					}
3548 				}
3549 				node->permissions |=
3550 				    (1 << (perdatum->s.value - 1));
3551 			}
3552 		}
3553 		free(id);
3554 	}
3555 
3556 	ebitmap_destroy(&classmap);
3557 
3558 	return 0;
3559 }
3560 
define_validatetrans(constraint_expr_t * expr)3561 int define_validatetrans(constraint_expr_t * expr)
3562 {
3563 	struct constraint_node *node;
3564 	char *id;
3565 	class_datum_t *cladatum;
3566 	ebitmap_t classmap;
3567 	constraint_expr_t *e;
3568 	int depth;
3569 	unsigned char useexpr = 1;
3570 
3571 	if (pass == 1) {
3572 		while ((id = queue_remove(id_queue)))
3573 			free(id);
3574 		return 0;
3575 	}
3576 
3577 	depth = -1;
3578 	for (e = expr; e; e = e->next) {
3579 		switch (e->expr_type) {
3580 		case CEXPR_NOT:
3581 			if (depth < 0) {
3582 				yyerror("illegal validatetrans expression");
3583 				return -1;
3584 			}
3585 			break;
3586 		case CEXPR_AND:
3587 		case CEXPR_OR:
3588 			if (depth < 1) {
3589 				yyerror("illegal validatetrans expression");
3590 				return -1;
3591 			}
3592 			depth--;
3593 			break;
3594 		case CEXPR_ATTR:
3595 		case CEXPR_NAMES:
3596 			if (depth == (CEXPR_MAXDEPTH - 1)) {
3597 				yyerror("validatetrans expression is too deep");
3598 				return -1;
3599 			}
3600 			depth++;
3601 			break;
3602 		default:
3603 			yyerror("illegal validatetrans expression");
3604 			return -1;
3605 		}
3606 	}
3607 	if (depth != 0) {
3608 		yyerror("illegal validatetrans expression");
3609 		return -1;
3610 	}
3611 
3612 	ebitmap_init(&classmap);
3613 	while ((id = queue_remove(id_queue))) {
3614 		if (!is_id_in_scope(SYM_CLASSES, id)) {
3615 			yyerror2("class %s is not within scope", id);
3616 			free(id);
3617 			return -1;
3618 		}
3619 		cladatum =
3620 		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3621 						     (hashtab_key_t) id);
3622 		if (!cladatum) {
3623 			yyerror2("class %s is not defined", id);
3624 			ebitmap_destroy(&classmap);
3625 			free(id);
3626 			return -1;
3627 		}
3628 		if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
3629 			yyerror("out of memory");
3630 			ebitmap_destroy(&classmap);
3631 			free(id);
3632 			return -1;
3633 		}
3634 
3635 		node = malloc(sizeof(struct constraint_node));
3636 		if (!node) {
3637 			yyerror("out of memory");
3638 			return -1;
3639 		}
3640 		memset(node, 0, sizeof(constraint_node_t));
3641 		if (useexpr) {
3642 			node->expr = expr;
3643 			useexpr = 0;
3644 		} else {
3645 			node->expr = constraint_expr_clone(expr);
3646 		}
3647 		node->permissions = 0;
3648 
3649 		node->next = cladatum->validatetrans;
3650 		cladatum->validatetrans = node;
3651 
3652 		free(id);
3653 	}
3654 
3655 	ebitmap_destroy(&classmap);
3656 
3657 	return 0;
3658 }
3659 
define_cexpr(uint32_t expr_type,uintptr_t arg1,uintptr_t arg2)3660 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
3661 {
3662 	struct constraint_expr *expr, *e1 = NULL, *e2;
3663 	user_datum_t *user;
3664 	role_datum_t *role;
3665 	ebitmap_t negset;
3666 	char *id;
3667 	uint32_t val;
3668 	int add = 1;
3669 
3670 	if (pass == 1) {
3671 		if (expr_type == CEXPR_NAMES) {
3672 			while ((id = queue_remove(id_queue)))
3673 				free(id);
3674 		}
3675 		return 1;	/* any non-NULL value */
3676 	}
3677 
3678 	if ((expr = malloc(sizeof(*expr))) == NULL ||
3679 	    constraint_expr_init(expr) == -1) {
3680 		yyerror("out of memory");
3681 		free(expr);
3682 		return 0;
3683 	}
3684 	expr->expr_type = expr_type;
3685 
3686 	switch (expr_type) {
3687 	case CEXPR_NOT:
3688 		e1 = NULL;
3689 		e2 = (struct constraint_expr *)arg1;
3690 		while (e2) {
3691 			e1 = e2;
3692 			e2 = e2->next;
3693 		}
3694 		if (!e1 || e1->next) {
3695 			yyerror("illegal constraint expression");
3696 			constraint_expr_destroy(expr);
3697 			return 0;
3698 		}
3699 		e1->next = expr;
3700 		return arg1;
3701 	case CEXPR_AND:
3702 	case CEXPR_OR:
3703 		e1 = NULL;
3704 		e2 = (struct constraint_expr *)arg1;
3705 		while (e2) {
3706 			e1 = e2;
3707 			e2 = e2->next;
3708 		}
3709 		if (!e1 || e1->next) {
3710 			yyerror("illegal constraint expression");
3711 			constraint_expr_destroy(expr);
3712 			return 0;
3713 		}
3714 		e1->next = (struct constraint_expr *)arg2;
3715 
3716 		e1 = NULL;
3717 		e2 = (struct constraint_expr *)arg2;
3718 		while (e2) {
3719 			e1 = e2;
3720 			e2 = e2->next;
3721 		}
3722 		if (!e1 || e1->next) {
3723 			yyerror("illegal constraint expression");
3724 			constraint_expr_destroy(expr);
3725 			return 0;
3726 		}
3727 		e1->next = expr;
3728 		return arg1;
3729 	case CEXPR_ATTR:
3730 		expr->attr = arg1;
3731 		expr->op = arg2;
3732 		return (uintptr_t) expr;
3733 	case CEXPR_NAMES:
3734 		add = 1;
3735 		expr->attr = arg1;
3736 		expr->op = arg2;
3737 		ebitmap_init(&negset);
3738 		while ((id = (char *)queue_remove(id_queue))) {
3739 			if (expr->attr & CEXPR_USER) {
3740 				if (!is_id_in_scope(SYM_USERS, id)) {
3741 					yyerror2("user %s is not within scope",
3742 						 id);
3743 					constraint_expr_destroy(expr);
3744 					return 0;
3745 				}
3746 				user =
3747 				    (user_datum_t *) hashtab_search(policydbp->
3748 								    p_users.
3749 								    table,
3750 								    (hashtab_key_t)
3751 								    id);
3752 				if (!user) {
3753 					yyerror2("unknown user %s", id);
3754 					constraint_expr_destroy(expr);
3755 					return 0;
3756 				}
3757 				val = user->s.value;
3758 			} else if (expr->attr & CEXPR_ROLE) {
3759 				if (!is_id_in_scope(SYM_ROLES, id)) {
3760 					yyerror2("role %s is not within scope",
3761 						 id);
3762 					constraint_expr_destroy(expr);
3763 					return 0;
3764 				}
3765 				role =
3766 				    (role_datum_t *) hashtab_search(policydbp->
3767 								    p_roles.
3768 								    table,
3769 								    (hashtab_key_t)
3770 								    id);
3771 				if (!role) {
3772 					yyerror2("unknown role %s", id);
3773 					constraint_expr_destroy(expr);
3774 					return 0;
3775 				}
3776 				val = role->s.value;
3777 			} else if (expr->attr & CEXPR_TYPE) {
3778 				if (set_types(expr->type_names, id, &add, 0)) {
3779 					constraint_expr_destroy(expr);
3780 					return 0;
3781 				}
3782 				continue;
3783 			} else {
3784 				yyerror("invalid constraint expression");
3785 				constraint_expr_destroy(expr);
3786 				return 0;
3787 			}
3788 			if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3789 				yyerror("out of memory");
3790 				ebitmap_destroy(&expr->names);
3791 				constraint_expr_destroy(expr);
3792 				return 0;
3793 			}
3794 			free(id);
3795 		}
3796 		ebitmap_destroy(&negset);
3797 		return (uintptr_t) expr;
3798 	default:
3799 		break;
3800 	}
3801 
3802 	yyerror("invalid constraint expression");
3803 	constraint_expr_destroy(expr);
3804 	return 0;
3805 }
3806 
define_conditional(cond_expr_t * expr,avrule_t * t,avrule_t * f)3807 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
3808 {
3809 	cond_expr_t *e;
3810 	int depth;
3811 	cond_node_t cn, *cn_old;
3812 
3813 	/* expression cannot be NULL */
3814 	if (!expr) {
3815 		yyerror("illegal conditional expression");
3816 		return -1;
3817 	}
3818 	if (!t) {
3819 		if (!f) {
3820 			/* empty is fine, destroy expression and return */
3821 			cond_expr_destroy(expr);
3822 			return 0;
3823 		}
3824 		/* Invert */
3825 		t = f;
3826 		f = 0;
3827 		expr = define_cond_expr(COND_NOT, expr, 0);
3828 		if (!expr) {
3829 			yyerror("unable to invert");
3830 			return -1;
3831 		}
3832 	}
3833 
3834 	/* verify expression */
3835 	depth = -1;
3836 	for (e = expr; e; e = e->next) {
3837 		switch (e->expr_type) {
3838 		case COND_NOT:
3839 			if (depth < 0) {
3840 				yyerror
3841 				    ("illegal conditional expression; Bad NOT");
3842 				return -1;
3843 			}
3844 			break;
3845 		case COND_AND:
3846 		case COND_OR:
3847 		case COND_XOR:
3848 		case COND_EQ:
3849 		case COND_NEQ:
3850 			if (depth < 1) {
3851 				yyerror
3852 				    ("illegal conditional expression; Bad binary op");
3853 				return -1;
3854 			}
3855 			depth--;
3856 			break;
3857 		case COND_BOOL:
3858 			if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3859 				yyerror
3860 				    ("conditional expression is like totally too deep");
3861 				return -1;
3862 			}
3863 			depth++;
3864 			break;
3865 		default:
3866 			yyerror("illegal conditional expression");
3867 			return -1;
3868 		}
3869 	}
3870 	if (depth != 0) {
3871 		yyerror("illegal conditional expression");
3872 		return -1;
3873 	}
3874 
3875 	/*  use tmp conditional node to partially build new node */
3876 	memset(&cn, 0, sizeof(cn));
3877 	cn.expr = expr;
3878 	cn.avtrue_list = t;
3879 	cn.avfalse_list = f;
3880 
3881 	/* normalize/precompute expression */
3882 	if (cond_normalize_expr(policydbp, &cn) < 0) {
3883 		yyerror("problem normalizing conditional expression");
3884 		return -1;
3885 	}
3886 
3887 	/* get the existing conditional node, or create a new one */
3888 	cn_old = get_current_cond_list(&cn);
3889 	if (!cn_old) {
3890 		return -1;
3891 	}
3892 
3893 	append_cond_list(&cn);
3894 
3895 	/* note that there is no check here for duplicate rules, nor
3896 	 * check that rule already exists in base -- that will be
3897 	 * handled during conditional expansion, in expand.c */
3898 
3899 	cn.avtrue_list = NULL;
3900 	cn.avfalse_list = NULL;
3901 	cond_node_destroy(&cn);
3902 
3903 	return 0;
3904 }
3905 
define_cond_expr(uint32_t expr_type,void * arg1,void * arg2)3906 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3907 {
3908 	struct cond_expr *expr, *e1 = NULL, *e2;
3909 	cond_bool_datum_t *bool_var;
3910 	char *id;
3911 
3912 	/* expressions are handled in the second pass */
3913 	if (pass == 1) {
3914 		if (expr_type == COND_BOOL) {
3915 			while ((id = queue_remove(id_queue))) {
3916 				free(id);
3917 			}
3918 		}
3919 		return (cond_expr_t *) 1;	/* any non-NULL value */
3920 	}
3921 
3922 	/* create a new expression struct */
3923 	expr = malloc(sizeof(struct cond_expr));
3924 	if (!expr) {
3925 		yyerror("out of memory");
3926 		return NULL;
3927 	}
3928 	memset(expr, 0, sizeof(cond_expr_t));
3929 	expr->expr_type = expr_type;
3930 
3931 	/* create the type asked for */
3932 	switch (expr_type) {
3933 	case COND_NOT:
3934 		e1 = NULL;
3935 		e2 = (struct cond_expr *)arg1;
3936 		while (e2) {
3937 			e1 = e2;
3938 			e2 = e2->next;
3939 		}
3940 		if (!e1 || e1->next) {
3941 			yyerror("illegal conditional NOT expression");
3942 			free(expr);
3943 			return NULL;
3944 		}
3945 		e1->next = expr;
3946 		return (struct cond_expr *)arg1;
3947 	case COND_AND:
3948 	case COND_OR:
3949 	case COND_XOR:
3950 	case COND_EQ:
3951 	case COND_NEQ:
3952 		e1 = NULL;
3953 		e2 = (struct cond_expr *)arg1;
3954 		while (e2) {
3955 			e1 = e2;
3956 			e2 = e2->next;
3957 		}
3958 		if (!e1 || e1->next) {
3959 			yyerror
3960 			    ("illegal left side of conditional binary op expression");
3961 			free(expr);
3962 			return NULL;
3963 		}
3964 		e1->next = (struct cond_expr *)arg2;
3965 
3966 		e1 = NULL;
3967 		e2 = (struct cond_expr *)arg2;
3968 		while (e2) {
3969 			e1 = e2;
3970 			e2 = e2->next;
3971 		}
3972 		if (!e1 || e1->next) {
3973 			yyerror
3974 			    ("illegal right side of conditional binary op expression");
3975 			free(expr);
3976 			return NULL;
3977 		}
3978 		e1->next = expr;
3979 		return (struct cond_expr *)arg1;
3980 	case COND_BOOL:
3981 		id = (char *)queue_remove(id_queue);
3982 		if (!id) {
3983 			yyerror("bad conditional; expected boolean id");
3984 			free(id);
3985 			free(expr);
3986 			return NULL;
3987 		}
3988 		if (!is_id_in_scope(SYM_BOOLS, id)) {
3989 			yyerror2("boolean %s is not within scope", id);
3990 			free(id);
3991 			free(expr);
3992 			return NULL;
3993 		}
3994 		bool_var =
3995 		    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
3996 							 table,
3997 							 (hashtab_key_t) id);
3998 		if (!bool_var) {
3999 			yyerror2("unknown boolean %s in conditional expression",
4000 				 id);
4001 			free(expr);
4002 			free(id);
4003 			return NULL;
4004 		}
4005 		expr->bool = bool_var->s.value;
4006 		free(id);
4007 		return expr;
4008 	default:
4009 		yyerror("illegal conditional expression");
4010 		free(expr);
4011 		return NULL;
4012 	}
4013 }
4014 
set_user_roles(role_set_t * set,char * id)4015 static int set_user_roles(role_set_t * set, char *id)
4016 {
4017 	role_datum_t *r;
4018 	unsigned int i;
4019 	ebitmap_node_t *node;
4020 
4021 	if (strcmp(id, "*") == 0) {
4022 		free(id);
4023 		yyerror("* is not allowed in user declarations");
4024 		return -1;
4025 	}
4026 
4027 	if (strcmp(id, "~") == 0) {
4028 		free(id);
4029 		yyerror("~ is not allowed in user declarations");
4030 		return -1;
4031 	}
4032 
4033 	if (!is_id_in_scope(SYM_ROLES, id)) {
4034 		yyerror2("role %s is not within scope", id);
4035 		free(id);
4036 		return -1;
4037 	}
4038 	r = hashtab_search(policydbp->p_roles.table, id);
4039 	if (!r) {
4040 		yyerror2("unknown role %s", id);
4041 		free(id);
4042 		return -1;
4043 	}
4044 
4045 	/* set the role and every role it dominates */
4046 	ebitmap_for_each_bit(&r->dominates, node, i) {
4047 		if (ebitmap_node_get_bit(node, i))
4048 			if (ebitmap_set_bit(&set->roles, i, TRUE))
4049 				goto oom;
4050 	}
4051 	free(id);
4052 	return 0;
4053       oom:
4054 	yyerror("out of memory");
4055 	return -1;
4056 }
4057 
parse_categories(char * id,level_datum_t * levdatum,ebitmap_t * cats)4058 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
4059 {
4060 	cat_datum_t *cdatum;
4061 	int range_start, range_end, i;
4062 
4063 	if (id_has_dot(id)) {
4064 		char *id_start = id;
4065 		char *id_end = strchr(id, '.');
4066 
4067 		*(id_end++) = '\0';
4068 
4069 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4070 							(hashtab_key_t)
4071 							id_start);
4072 		if (!cdatum) {
4073 			yyerror2("unknown category %s", id_start);
4074 			return -1;
4075 		}
4076 		range_start = cdatum->s.value - 1;
4077 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4078 							(hashtab_key_t) id_end);
4079 		if (!cdatum) {
4080 			yyerror2("unknown category %s", id_end);
4081 			return -1;
4082 		}
4083 		range_end = cdatum->s.value - 1;
4084 
4085 		if (range_end < range_start) {
4086 			yyerror2("category range is invalid");
4087 			return -1;
4088 		}
4089 	} else {
4090 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4091 							(hashtab_key_t) id);
4092 		if (!cdatum) {
4093 			yyerror2("unknown category %s", id);
4094 			return -1;
4095 		}
4096 		range_start = range_end = cdatum->s.value - 1;
4097 	}
4098 
4099 	for (i = range_start; i <= range_end; i++) {
4100 		if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
4101 			uint32_t level_value = levdatum->level->sens - 1;
4102 			policydb_index_others(NULL, policydbp, 0);
4103 			yyerror2("category %s can not be associated "
4104 				 "with level %s",
4105 				 policydbp->p_cat_val_to_name[i],
4106 				 policydbp->p_sens_val_to_name[level_value]);
4107 			return -1;
4108 		}
4109 		if (ebitmap_set_bit(cats, i, TRUE)) {
4110 			yyerror("out of memory");
4111 			return -1;
4112 		}
4113 	}
4114 
4115 	return 0;
4116 }
4117 
parse_semantic_categories(char * id,level_datum_t * levdatum,mls_semantic_cat_t ** cats)4118 static int parse_semantic_categories(char *id, level_datum_t * levdatum __attribute__ ((unused)),
4119 				     mls_semantic_cat_t ** cats)
4120 {
4121 	cat_datum_t *cdatum;
4122 	mls_semantic_cat_t *newcat;
4123 	unsigned int range_start, range_end;
4124 
4125 	if (id_has_dot(id)) {
4126 		char *id_start = id;
4127 		char *id_end = strchr(id, '.');
4128 
4129 		*(id_end++) = '\0';
4130 
4131 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4132 							(hashtab_key_t)
4133 							id_start);
4134 		if (!cdatum) {
4135 			yyerror2("unknown category %s", id_start);
4136 			return -1;
4137 		}
4138 		range_start = cdatum->s.value;
4139 
4140 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4141 							(hashtab_key_t) id_end);
4142 		if (!cdatum) {
4143 			yyerror2("unknown category %s", id_end);
4144 			return -1;
4145 		}
4146 		range_end = cdatum->s.value;
4147 	} else {
4148 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4149 							(hashtab_key_t) id);
4150 		if (!cdatum) {
4151 			yyerror2("unknown category %s", id);
4152 			return -1;
4153 		}
4154 		range_start = range_end = cdatum->s.value;
4155 	}
4156 
4157 	newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
4158 	if (!newcat) {
4159 		yyerror("out of memory");
4160 		return -1;
4161 	}
4162 
4163 	mls_semantic_cat_init(newcat);
4164 	newcat->next = *cats;
4165 	newcat->low = range_start;
4166 	newcat->high = range_end;
4167 
4168 	*cats = newcat;
4169 
4170 	return 0;
4171 }
4172 
define_user(void)4173 int define_user(void)
4174 {
4175 	char *id;
4176 	user_datum_t *usrdatum;
4177 	level_datum_t *levdatum;
4178 	int l;
4179 
4180 	if (pass == 1) {
4181 		while ((id = queue_remove(id_queue)))
4182 			free(id);
4183 		if (mlspol) {
4184 			while ((id = queue_remove(id_queue)))
4185 				free(id);
4186 			id = queue_remove(id_queue);
4187 			free(id);
4188 			for (l = 0; l < 2; l++) {
4189 				while ((id = queue_remove(id_queue))) {
4190 					free(id);
4191 				}
4192 				id = queue_remove(id_queue);
4193 				if (!id)
4194 					break;
4195 				free(id);
4196 			}
4197 		}
4198 		return 0;
4199 	}
4200 
4201 	if ((usrdatum = declare_user()) == NULL) {
4202 		return -1;
4203 	}
4204 
4205 	while ((id = queue_remove(id_queue))) {
4206 		if (set_user_roles(&usrdatum->roles, id))
4207 			continue;
4208 	}
4209 
4210 	if (mlspol) {
4211 		id = queue_remove(id_queue);
4212 		if (!id) {
4213 			yyerror("no default level specified for user");
4214 			return -1;
4215 		}
4216 
4217 		levdatum = (level_datum_t *)
4218 		    hashtab_search(policydbp->p_levels.table,
4219 				   (hashtab_key_t) id);
4220 		if (!levdatum) {
4221 			yyerror2("unknown sensitivity %s used in user"
4222 				 " level definition", id);
4223 			free(id);
4224 			return -1;
4225 		}
4226 		free(id);
4227 
4228 		usrdatum->dfltlevel.sens = levdatum->level->sens;
4229 
4230 		while ((id = queue_remove(id_queue))) {
4231 			if (parse_semantic_categories(id, levdatum,
4232 			                            &usrdatum->dfltlevel.cat)) {
4233 				free(id);
4234 				return -1;
4235 			}
4236 			free(id);
4237 		}
4238 
4239 		id = queue_remove(id_queue);
4240 
4241 		for (l = 0; l < 2; l++) {
4242 			levdatum = (level_datum_t *)
4243 			    hashtab_search(policydbp->p_levels.table,
4244 					   (hashtab_key_t) id);
4245 			if (!levdatum) {
4246 				yyerror2("unknown sensitivity %s used in user"
4247 					 " range definition", id);
4248 				free(id);
4249 				return -1;
4250 			}
4251 			free(id);
4252 
4253 			usrdatum->range.level[l].sens = levdatum->level->sens;
4254 
4255 			while ((id = queue_remove(id_queue))) {
4256 				if (parse_semantic_categories(id, levdatum,
4257 				               &usrdatum->range.level[l].cat)) {
4258 					free(id);
4259 					return -1;
4260 				}
4261 				free(id);
4262 			}
4263 
4264 			id = queue_remove(id_queue);
4265 			if (!id)
4266 				break;
4267 		}
4268 
4269 		if (l == 0) {
4270 			if (mls_semantic_level_cpy(&usrdatum->range.level[1],
4271 			                           &usrdatum->range.level[0])) {
4272 				yyerror("out of memory");
4273 				return -1;
4274 			}
4275 		}
4276 	}
4277 	return 0;
4278 }
4279 
parse_security_context(context_struct_t * c)4280 static int parse_security_context(context_struct_t * c)
4281 {
4282 	char *id;
4283 	role_datum_t *role;
4284 	type_datum_t *typdatum;
4285 	user_datum_t *usrdatum;
4286 	level_datum_t *levdatum;
4287 	int l;
4288 
4289 	if (pass == 1) {
4290 		id = queue_remove(id_queue);
4291 		free(id);	/* user  */
4292 		id = queue_remove(id_queue);
4293 		free(id);	/* role  */
4294 		id = queue_remove(id_queue);
4295 		free(id);	/* type  */
4296 		if (mlspol) {
4297 			id = queue_remove(id_queue);
4298 			free(id);
4299 			for (l = 0; l < 2; l++) {
4300 				while ((id = queue_remove(id_queue))) {
4301 					free(id);
4302 				}
4303 				id = queue_remove(id_queue);
4304 				if (!id)
4305 					break;
4306 				free(id);
4307 			}
4308 		}
4309 		return 0;
4310 	}
4311 
4312 	/* check context c to make sure ok to dereference c later */
4313 	if (c == NULL) {
4314 		yyerror("null context pointer!");
4315 		return -1;
4316 	}
4317 
4318 	context_init(c);
4319 
4320 	/* extract the user */
4321 	id = queue_remove(id_queue);
4322 	if (!id) {
4323 		yyerror("no effective user?");
4324 		goto bad;
4325 	}
4326 	if (!is_id_in_scope(SYM_USERS, id)) {
4327 		yyerror2("user %s is not within scope", id);
4328 		free(id);
4329 		goto bad;
4330 	}
4331 	usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
4332 						   (hashtab_key_t) id);
4333 	if (!usrdatum) {
4334 		yyerror2("user %s is not defined", id);
4335 		free(id);
4336 		goto bad;
4337 	}
4338 	c->user = usrdatum->s.value;
4339 
4340 	/* no need to keep the user name */
4341 	free(id);
4342 
4343 	/* extract the role */
4344 	id = (char *)queue_remove(id_queue);
4345 	if (!id) {
4346 		yyerror("no role name for sid context definition?");
4347 		return -1;
4348 	}
4349 	if (!is_id_in_scope(SYM_ROLES, id)) {
4350 		yyerror2("role %s is not within scope", id);
4351 		free(id);
4352 		return -1;
4353 	}
4354 	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
4355 					       (hashtab_key_t) id);
4356 	if (!role) {
4357 		yyerror2("role %s is not defined", id);
4358 		free(id);
4359 		return -1;
4360 	}
4361 	c->role = role->s.value;
4362 
4363 	/* no need to keep the role name */
4364 	free(id);
4365 
4366 	/* extract the type */
4367 	id = (char *)queue_remove(id_queue);
4368 	if (!id) {
4369 		yyerror("no type name for sid context definition?");
4370 		return -1;
4371 	}
4372 	if (!is_id_in_scope(SYM_TYPES, id)) {
4373 		yyerror2("type %s is not within scope", id);
4374 		free(id);
4375 		return -1;
4376 	}
4377 	typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
4378 						   (hashtab_key_t) id);
4379 	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
4380 		yyerror2("type %s is not defined or is an attribute", id);
4381 		free(id);
4382 		return -1;
4383 	}
4384 	c->type = typdatum->s.value;
4385 
4386 	/* no need to keep the type name */
4387 	free(id);
4388 
4389 	if (mlspol) {
4390 		/* extract the low sensitivity */
4391 		id = (char *)queue_head(id_queue);
4392 		if (!id) {
4393 			yyerror("no sensitivity name for sid context"
4394 				" definition?");
4395 			return -1;
4396 		}
4397 
4398 		id = (char *)queue_remove(id_queue);
4399 		for (l = 0; l < 2; l++) {
4400 			levdatum = (level_datum_t *)
4401 			    hashtab_search(policydbp->p_levels.table,
4402 					   (hashtab_key_t) id);
4403 			if (!levdatum) {
4404 				yyerror2("Sensitivity %s is not defined", id);
4405 				free(id);
4406 				return -1;
4407 			}
4408 			free(id);
4409 			c->range.level[l].sens = levdatum->level->sens;
4410 
4411 			/* extract low category set */
4412 			while ((id = queue_remove(id_queue))) {
4413 				if (parse_categories(id, levdatum,
4414 						     &c->range.level[l].cat)) {
4415 					free(id);
4416 					return -1;
4417 				}
4418 				free(id);
4419 			}
4420 
4421 			/* extract high sensitivity */
4422 			id = (char *)queue_remove(id_queue);
4423 			if (!id)
4424 				break;
4425 		}
4426 
4427 		if (l == 0) {
4428 			c->range.level[1].sens = c->range.level[0].sens;
4429 			if (ebitmap_cpy(&c->range.level[1].cat,
4430 					&c->range.level[0].cat)) {
4431 
4432 				yyerror("out of memory");
4433 				goto bad;
4434 			}
4435 		}
4436 	}
4437 
4438 	if (!policydb_context_isvalid(policydbp, c)) {
4439 		yyerror("invalid security context");
4440 		goto bad;
4441 	}
4442 	return 0;
4443 
4444       bad:
4445 	context_destroy(c);
4446 
4447 	return -1;
4448 }
4449 
define_initial_sid_context(void)4450 int define_initial_sid_context(void)
4451 {
4452 	char *id;
4453 	ocontext_t *c, *head;
4454 
4455 	if (pass == 1) {
4456 		id = (char *)queue_remove(id_queue);
4457 		free(id);
4458 		parse_security_context(NULL);
4459 		return 0;
4460 	}
4461 
4462 	id = (char *)queue_remove(id_queue);
4463 	if (!id) {
4464 		yyerror("no sid name for SID context definition?");
4465 		return -1;
4466 	}
4467 	head = policydbp->ocontexts[OCON_ISID];
4468 	for (c = head; c; c = c->next) {
4469 		if (!strcmp(id, c->u.name))
4470 			break;
4471 	}
4472 
4473 	if (!c) {
4474 		yyerror2("SID %s is not defined", id);
4475 		free(id);
4476 		return -1;
4477 	}
4478 	if (c->context[0].user) {
4479 		yyerror2("The context for SID %s is multiply defined", id);
4480 		free(id);
4481 		return -1;
4482 	}
4483 	/* no need to keep the sid name */
4484 	free(id);
4485 
4486 	if (parse_security_context(&c->context[0]))
4487 		return -1;
4488 
4489 	return 0;
4490 }
4491 
define_fs_context(unsigned int major,unsigned int minor)4492 int define_fs_context(unsigned int major, unsigned int minor)
4493 {
4494 	ocontext_t *newc, *c, *head;
4495 
4496 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4497 		yyerror("fscon not supported for target");
4498 		return -1;
4499 	}
4500 
4501 	if (pass == 1) {
4502 		parse_security_context(NULL);
4503 		parse_security_context(NULL);
4504 		return 0;
4505 	}
4506 
4507 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4508 	if (!newc) {
4509 		yyerror("out of memory");
4510 		return -1;
4511 	}
4512 	memset(newc, 0, sizeof(ocontext_t));
4513 
4514 	newc->u.name = (char *)malloc(6);
4515 	if (!newc->u.name) {
4516 		yyerror("out of memory");
4517 		free(newc);
4518 		return -1;
4519 	}
4520 	sprintf(newc->u.name, "%02x:%02x", major, minor);
4521 
4522 	if (parse_security_context(&newc->context[0])) {
4523 		free(newc->u.name);
4524 		free(newc);
4525 		return -1;
4526 	}
4527 	if (parse_security_context(&newc->context[1])) {
4528 		context_destroy(&newc->context[0]);
4529 		free(newc->u.name);
4530 		free(newc);
4531 		return -1;
4532 	}
4533 	head = policydbp->ocontexts[OCON_FS];
4534 
4535 	for (c = head; c; c = c->next) {
4536 		if (!strcmp(newc->u.name, c->u.name)) {
4537 			yyerror2("duplicate entry for file system %s",
4538 				 newc->u.name);
4539 			context_destroy(&newc->context[0]);
4540 			context_destroy(&newc->context[1]);
4541 			free(newc->u.name);
4542 			free(newc);
4543 			return -1;
4544 		}
4545 	}
4546 
4547 	newc->next = head;
4548 	policydbp->ocontexts[OCON_FS] = newc;
4549 
4550 	return 0;
4551 }
4552 
define_pirq_context(unsigned int pirq)4553 int define_pirq_context(unsigned int pirq)
4554 {
4555 	ocontext_t *newc, *c, *l, *head;
4556 	char *id;
4557 
4558 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4559 		yyerror("pirqcon not supported for target");
4560 		return -1;
4561 	}
4562 
4563 	if (pass == 1) {
4564 		id = (char *) queue_remove(id_queue);
4565 		free(id);
4566 		parse_security_context(NULL);
4567 		return 0;
4568 	}
4569 
4570 	newc = malloc(sizeof(ocontext_t));
4571 	if (!newc) {
4572 		yyerror("out of memory");
4573 		return -1;
4574 	}
4575 	memset(newc, 0, sizeof(ocontext_t));
4576 
4577 	newc->u.pirq = pirq;
4578 
4579 	if (parse_security_context(&newc->context[0])) {
4580 		free(newc);
4581 		return -1;
4582 	}
4583 
4584 	head = policydbp->ocontexts[OCON_XEN_PIRQ];
4585 	for (l = NULL, c = head; c; l = c, c = c->next) {
4586 		unsigned int pirq2;
4587 
4588 		pirq2 = c->u.pirq;
4589 		if (pirq == pirq2) {
4590 			yyerror2("duplicate pirqcon entry for %d ", pirq);
4591 			goto bad;
4592 		}
4593 	}
4594 
4595 	if (l)
4596 		l->next = newc;
4597 	else
4598 		policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
4599 
4600 	return 0;
4601 
4602 bad:
4603 	free(newc);
4604 	return -1;
4605 }
4606 
define_iomem_context(uint64_t low,uint64_t high)4607 int define_iomem_context(uint64_t low, uint64_t high)
4608 {
4609 	ocontext_t *newc, *c, *l, *head;
4610 	char *id;
4611 
4612 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4613 		yyerror("iomemcon not supported for target");
4614 		return -1;
4615 	}
4616 
4617 	if (pass == 1) {
4618 		id = (char *)queue_remove(id_queue);
4619 		free(id);
4620 		parse_security_context(NULL);
4621 		return 0;
4622 	}
4623 
4624 	newc = malloc(sizeof(ocontext_t));
4625 	if (!newc) {
4626 		yyerror("out of memory");
4627 		return -1;
4628 	}
4629 	memset(newc, 0, sizeof(ocontext_t));
4630 
4631 	newc->u.iomem.low_iomem  = low;
4632 	newc->u.iomem.high_iomem = high;
4633 
4634 	if (low > high) {
4635 		yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high);
4636 		free(newc);
4637 		return -1;
4638 	}
4639 
4640 	if (parse_security_context(&newc->context[0])) {
4641 		free(newc);
4642 		return -1;
4643 	}
4644 
4645 	head = policydbp->ocontexts[OCON_XEN_IOMEM];
4646 	for (l = NULL, c = head; c; l = c, c = c->next) {
4647 		uint64_t low2, high2;
4648 
4649 		low2 = c->u.iomem.low_iomem;
4650 		high2 = c->u.iomem.high_iomem;
4651 		if (low <= high2 && low2 <= high) {
4652 			yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with "
4653 				"earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high,
4654 				low2, high2);
4655 			goto bad;
4656 		}
4657 	}
4658 
4659 	if (l)
4660 		l->next = newc;
4661 	else
4662 		policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
4663 
4664 	return 0;
4665 
4666 bad:
4667 	free(newc);
4668 	return -1;
4669 }
4670 
define_ioport_context(unsigned long low,unsigned long high)4671 int define_ioport_context(unsigned long low, unsigned long high)
4672 {
4673 	ocontext_t *newc, *c, *l, *head;
4674 	char *id;
4675 
4676 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4677 		yyerror("ioportcon not supported for target");
4678 		return -1;
4679 	}
4680 
4681 	if (pass == 1) {
4682 		id = (char *)queue_remove(id_queue);
4683 		free(id);
4684 		parse_security_context(NULL);
4685 		return 0;
4686 	}
4687 
4688 	newc = malloc(sizeof(ocontext_t));
4689 	if (!newc) {
4690 		yyerror("out of memory");
4691 		return -1;
4692 	}
4693 	memset(newc, 0, sizeof(ocontext_t));
4694 
4695 	newc->u.ioport.low_ioport  = low;
4696 	newc->u.ioport.high_ioport = high;
4697 
4698 	if (low > high) {
4699 		yyerror2("low ioport 0x%lx exceeds high ioport 0x%lx", low, high);
4700 		free(newc);
4701 		return -1;
4702 	}
4703 
4704 	if (parse_security_context(&newc->context[0])) {
4705 		free(newc);
4706 		return -1;
4707 	}
4708 
4709 	head = policydbp->ocontexts[OCON_XEN_IOPORT];
4710 	for (l = NULL, c = head; c; l = c, c = c->next) {
4711 		uint32_t low2, high2;
4712 
4713 		low2 = c->u.ioport.low_ioport;
4714 		high2 = c->u.ioport.high_ioport;
4715 		if (low <= high2 && low2 <= high) {
4716 			yyerror2("ioportcon entry for 0x%lx-0x%lx overlaps with"
4717 				"earlier entry 0x%x-0x%x", low, high,
4718 				low2, high2);
4719 			goto bad;
4720 		}
4721 	}
4722 
4723 	if (l)
4724 		l->next = newc;
4725 	else
4726 		policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
4727 
4728 	return 0;
4729 
4730 bad:
4731 	free(newc);
4732 	return -1;
4733 }
4734 
define_pcidevice_context(unsigned long device)4735 int define_pcidevice_context(unsigned long device)
4736 {
4737 	ocontext_t *newc, *c, *l, *head;
4738 	char *id;
4739 
4740 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4741 		yyerror("pcidevicecon not supported for target");
4742 		return -1;
4743 	}
4744 
4745 	if (pass == 1) {
4746 		id = (char *) queue_remove(id_queue);
4747 		free(id);
4748 		parse_security_context(NULL);
4749 		return 0;
4750 	}
4751 
4752 	newc = malloc(sizeof(ocontext_t));
4753 	if (!newc) {
4754 		yyerror("out of memory");
4755 		return -1;
4756 	}
4757 	memset(newc, 0, sizeof(ocontext_t));
4758 
4759 	newc->u.device = device;
4760 
4761 	if (parse_security_context(&newc->context[0])) {
4762 		free(newc);
4763 		return -1;
4764 	}
4765 
4766 	head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
4767 	for (l = NULL, c = head; c; l = c, c = c->next) {
4768 		unsigned int device2;
4769 
4770 		device2 = c->u.device;
4771 		if (device == device2) {
4772 			yyerror2("duplicate pcidevicecon entry for 0x%lx",
4773 				 device);
4774 			goto bad;
4775 		}
4776 	}
4777 
4778 	if (l)
4779 		l->next = newc;
4780 	else
4781 		policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
4782 
4783 	return 0;
4784 
4785 bad:
4786 	free(newc);
4787 	return -1;
4788 }
4789 
define_devicetree_context()4790 int define_devicetree_context()
4791 {
4792 	ocontext_t *newc, *c, *l, *head;
4793 
4794 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4795 		yyerror("devicetreecon not supported for target");
4796 		return -1;
4797 	}
4798 
4799 	if (pass == 1) {
4800 		free(queue_remove(id_queue));
4801 		parse_security_context(NULL);
4802 		return 0;
4803 	}
4804 
4805 	newc = malloc(sizeof(ocontext_t));
4806 	if (!newc) {
4807 		yyerror("out of memory");
4808 		return -1;
4809 	}
4810 	memset(newc, 0, sizeof(ocontext_t));
4811 
4812 	newc->u.name = (char *)queue_remove(id_queue);
4813 	if (!newc->u.name) {
4814 		free(newc);
4815 		return -1;
4816 	}
4817 
4818 	if (parse_security_context(&newc->context[0])) {
4819 		free(newc->u.name);
4820 		free(newc);
4821 		return -1;
4822 	}
4823 
4824 	head = policydbp->ocontexts[OCON_XEN_DEVICETREE];
4825 	for (l = NULL, c = head; c; l = c, c = c->next) {
4826 		if (strcmp(newc->u.name, c->u.name) == 0) {
4827 			yyerror2("duplicate devicetree entry for '%s'", newc->u.name);
4828 			goto bad;
4829 		}
4830 	}
4831 
4832 	if (l)
4833 		l->next = newc;
4834 	else
4835 		policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc;
4836 
4837 	return 0;
4838 
4839 bad:
4840 	free(newc->u.name);
4841 	free(newc);
4842 	return -1;
4843 }
4844 
define_port_context(unsigned int low,unsigned int high)4845 int define_port_context(unsigned int low, unsigned int high)
4846 {
4847 	ocontext_t *newc, *c, *l, *head;
4848 	unsigned int protocol;
4849 	char *id;
4850 
4851 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4852 		yyerror("portcon not supported for target");
4853 		return -1;
4854 	}
4855 
4856 	if (pass == 1) {
4857 		id = (char *)queue_remove(id_queue);
4858 		free(id);
4859 		parse_security_context(NULL);
4860 		return 0;
4861 	}
4862 
4863 	newc = malloc(sizeof(ocontext_t));
4864 	if (!newc) {
4865 		yyerror("out of memory");
4866 		return -1;
4867 	}
4868 	memset(newc, 0, sizeof(ocontext_t));
4869 
4870 	id = (char *)queue_remove(id_queue);
4871 	if (!id) {
4872 		free(newc);
4873 		return -1;
4874 	}
4875 	if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4876 		protocol = IPPROTO_TCP;
4877 	} else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4878 		protocol = IPPROTO_UDP;
4879 	} else {
4880 		yyerror2("unrecognized protocol %s", id);
4881 		free(newc);
4882 		return -1;
4883 	}
4884 
4885 	newc->u.port.protocol = protocol;
4886 	newc->u.port.low_port = low;
4887 	newc->u.port.high_port = high;
4888 
4889 	if (low > high) {
4890 		yyerror2("low port %d exceeds high port %d", low, high);
4891 		free(newc);
4892 		return -1;
4893 	}
4894 
4895 	if (parse_security_context(&newc->context[0])) {
4896 		free(newc);
4897 		return -1;
4898 	}
4899 
4900 	/* Preserve the matching order specified in the configuration. */
4901 	head = policydbp->ocontexts[OCON_PORT];
4902 	for (l = NULL, c = head; c; l = c, c = c->next) {
4903 		unsigned int prot2, low2, high2;
4904 
4905 		prot2 = c->u.port.protocol;
4906 		low2 = c->u.port.low_port;
4907 		high2 = c->u.port.high_port;
4908 		if (protocol != prot2)
4909 			continue;
4910 		if (low == low2 && high == high2) {
4911 			yyerror2("duplicate portcon entry for %s %d-%d ", id,
4912 				 low, high);
4913 			goto bad;
4914 		}
4915 		if (low2 <= low && high2 >= high) {
4916 			yyerror2("portcon entry for %s %d-%d hidden by earlier "
4917 				 "entry for %d-%d", id, low, high, low2, high2);
4918 			goto bad;
4919 		}
4920 	}
4921 
4922 	if (l)
4923 		l->next = newc;
4924 	else
4925 		policydbp->ocontexts[OCON_PORT] = newc;
4926 
4927 	return 0;
4928 
4929       bad:
4930 	free(newc);
4931 	return -1;
4932 }
4933 
define_netif_context(void)4934 int define_netif_context(void)
4935 {
4936 	ocontext_t *newc, *c, *head;
4937 
4938 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4939 		yyerror("netifcon not supported for target");
4940 		return -1;
4941 	}
4942 
4943 	if (pass == 1) {
4944 		free(queue_remove(id_queue));
4945 		parse_security_context(NULL);
4946 		parse_security_context(NULL);
4947 		return 0;
4948 	}
4949 
4950 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4951 	if (!newc) {
4952 		yyerror("out of memory");
4953 		return -1;
4954 	}
4955 	memset(newc, 0, sizeof(ocontext_t));
4956 
4957 	newc->u.name = (char *)queue_remove(id_queue);
4958 	if (!newc->u.name) {
4959 		free(newc);
4960 		return -1;
4961 	}
4962 	if (parse_security_context(&newc->context[0])) {
4963 		free(newc->u.name);
4964 		free(newc);
4965 		return -1;
4966 	}
4967 	if (parse_security_context(&newc->context[1])) {
4968 		context_destroy(&newc->context[0]);
4969 		free(newc->u.name);
4970 		free(newc);
4971 		return -1;
4972 	}
4973 	head = policydbp->ocontexts[OCON_NETIF];
4974 
4975 	for (c = head; c; c = c->next) {
4976 		if (!strcmp(newc->u.name, c->u.name)) {
4977 			yyerror2("duplicate entry for network interface %s",
4978 				 newc->u.name);
4979 			context_destroy(&newc->context[0]);
4980 			context_destroy(&newc->context[1]);
4981 			free(newc->u.name);
4982 			free(newc);
4983 			return -1;
4984 		}
4985 	}
4986 
4987 	newc->next = head;
4988 	policydbp->ocontexts[OCON_NETIF] = newc;
4989 	return 0;
4990 }
4991 
define_ipv4_node_context()4992 int define_ipv4_node_context()
4993 {
4994 	char *id;
4995 	int rc = 0;
4996 	struct in_addr addr, mask;
4997 	ocontext_t *newc, *c, *l, *head;
4998 
4999 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5000 		yyerror("nodecon not supported for target");
5001 		return -1;
5002 	}
5003 
5004 	if (pass == 1) {
5005 		free(queue_remove(id_queue));
5006 		free(queue_remove(id_queue));
5007 		parse_security_context(NULL);
5008 		goto out;
5009 	}
5010 
5011 	id = queue_remove(id_queue);
5012 	if (!id) {
5013 		yyerror("failed to read ipv4 address");
5014 		rc = -1;
5015 		goto out;
5016 	}
5017 
5018 	rc = inet_pton(AF_INET, id, &addr);
5019 	free(id);
5020 	if (rc < 1) {
5021 		yyerror("failed to parse ipv4 address");
5022 		if (rc == 0)
5023 			rc = -1;
5024 		goto out;
5025 	}
5026 
5027 	id = queue_remove(id_queue);
5028 	if (!id) {
5029 		yyerror("failed to read ipv4 address");
5030 		rc = -1;
5031 		goto out;
5032 	}
5033 
5034 	rc = inet_pton(AF_INET, id, &mask);
5035 	free(id);
5036 	if (rc < 1) {
5037 		yyerror("failed to parse ipv4 mask");
5038 		if (rc == 0)
5039 			rc = -1;
5040 		goto out;
5041 	}
5042 
5043 	newc = malloc(sizeof(ocontext_t));
5044 	if (!newc) {
5045 		yyerror("out of memory");
5046 		rc = -1;
5047 		goto out;
5048 	}
5049 
5050 	memset(newc, 0, sizeof(ocontext_t));
5051 	newc->u.node.addr = addr.s_addr;
5052 	newc->u.node.mask = mask.s_addr;
5053 
5054 	if (parse_security_context(&newc->context[0])) {
5055 		free(newc);
5056 		return -1;
5057 	}
5058 
5059 	/* Create order of most specific to least retaining
5060 	   the order specified in the configuration. */
5061 	head = policydbp->ocontexts[OCON_NODE];
5062 	for (l = NULL, c = head; c; l = c, c = c->next) {
5063 		if (newc->u.node.mask > c->u.node.mask)
5064 			break;
5065 	}
5066 
5067 	newc->next = c;
5068 
5069 	if (l)
5070 		l->next = newc;
5071 	else
5072 		policydbp->ocontexts[OCON_NODE] = newc;
5073 	rc = 0;
5074 out:
5075 	return rc;
5076 }
5077 
define_ipv6_node_context(void)5078 int define_ipv6_node_context(void)
5079 {
5080 	char *id;
5081 	int rc = 0;
5082 	struct in6_addr addr, mask;
5083 	ocontext_t *newc, *c, *l, *head;
5084 
5085 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5086 		yyerror("nodecon not supported for target");
5087 		return -1;
5088 	}
5089 
5090 	if (pass == 1) {
5091 		free(queue_remove(id_queue));
5092 		free(queue_remove(id_queue));
5093 		parse_security_context(NULL);
5094 		goto out;
5095 	}
5096 
5097 	id = queue_remove(id_queue);
5098 	if (!id) {
5099 		yyerror("failed to read ipv6 address");
5100 		rc = -1;
5101 		goto out;
5102 	}
5103 
5104 	rc = inet_pton(AF_INET6, id, &addr);
5105 	free(id);
5106 	if (rc < 1) {
5107 		yyerror("failed to parse ipv6 address");
5108 		if (rc == 0)
5109 			rc = -1;
5110 		goto out;
5111 	}
5112 
5113 	id = queue_remove(id_queue);
5114 	if (!id) {
5115 		yyerror("failed to read ipv6 address");
5116 		rc = -1;
5117 		goto out;
5118 	}
5119 
5120 	rc = inet_pton(AF_INET6, id, &mask);
5121 	free(id);
5122 	if (rc < 1) {
5123 		yyerror("failed to parse ipv6 mask");
5124 		if (rc == 0)
5125 			rc = -1;
5126 		goto out;
5127 	}
5128 
5129 	newc = malloc(sizeof(ocontext_t));
5130 	if (!newc) {
5131 		yyerror("out of memory");
5132 		rc = -1;
5133 		goto out;
5134 	}
5135 
5136 	memset(newc, 0, sizeof(ocontext_t));
5137 
5138 #ifdef DARWIN
5139 	memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
5140 	memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
5141 #else
5142 	memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
5143 	memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
5144 #endif
5145 
5146 	if (parse_security_context(&newc->context[0])) {
5147 		free(newc);
5148 		rc = -1;
5149 		goto out;
5150 	}
5151 
5152 	/* Create order of most specific to least retaining
5153 	   the order specified in the configuration. */
5154 	head = policydbp->ocontexts[OCON_NODE6];
5155 	for (l = NULL, c = head; c; l = c, c = c->next) {
5156 		if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
5157 			break;
5158 	}
5159 
5160 	newc->next = c;
5161 
5162 	if (l)
5163 		l->next = newc;
5164 	else
5165 		policydbp->ocontexts[OCON_NODE6] = newc;
5166 
5167 	rc = 0;
5168       out:
5169 	return rc;
5170 }
5171 
define_fs_use(int behavior)5172 int define_fs_use(int behavior)
5173 {
5174 	ocontext_t *newc, *c, *head;
5175 
5176 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5177 		yyerror("fsuse not supported for target");
5178 		return -1;
5179 	}
5180 
5181 	if (pass == 1) {
5182 		free(queue_remove(id_queue));
5183 		parse_security_context(NULL);
5184 		return 0;
5185 	}
5186 
5187 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5188 	if (!newc) {
5189 		yyerror("out of memory");
5190 		return -1;
5191 	}
5192 	memset(newc, 0, sizeof(ocontext_t));
5193 
5194 	newc->u.name = (char *)queue_remove(id_queue);
5195 	if (!newc->u.name) {
5196 		free(newc);
5197 		return -1;
5198 	}
5199 	newc->v.behavior = behavior;
5200 	if (parse_security_context(&newc->context[0])) {
5201 		free(newc->u.name);
5202 		free(newc);
5203 		return -1;
5204 	}
5205 
5206 	head = policydbp->ocontexts[OCON_FSUSE];
5207 
5208 	for (c = head; c; c = c->next) {
5209 		if (!strcmp(newc->u.name, c->u.name)) {
5210 			yyerror2("duplicate fs_use entry for filesystem type %s",
5211 				 newc->u.name);
5212 			context_destroy(&newc->context[0]);
5213 			free(newc->u.name);
5214 			free(newc);
5215 			return -1;
5216 		}
5217 	}
5218 
5219 	newc->next = head;
5220 	policydbp->ocontexts[OCON_FSUSE] = newc;
5221 	return 0;
5222 }
5223 
define_genfs_context_helper(char * fstype,int has_type)5224 int define_genfs_context_helper(char *fstype, int has_type)
5225 {
5226 	struct genfs *genfs_p, *genfs, *newgenfs;
5227 	ocontext_t *newc, *c, *head, *p;
5228 	char *type = NULL;
5229 	int len, len2;
5230 
5231 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5232 		yyerror("genfs not supported for target");
5233 		return -1;
5234 	}
5235 
5236 	if (pass == 1) {
5237 		free(fstype);
5238 		free(queue_remove(id_queue));
5239 		if (has_type)
5240 			free(queue_remove(id_queue));
5241 		parse_security_context(NULL);
5242 		return 0;
5243 	}
5244 
5245 	for (genfs_p = NULL, genfs = policydbp->genfs;
5246 	     genfs; genfs_p = genfs, genfs = genfs->next) {
5247 		if (strcmp(fstype, genfs->fstype) <= 0)
5248 			break;
5249 	}
5250 
5251 	if (!genfs || strcmp(fstype, genfs->fstype)) {
5252 		newgenfs = malloc(sizeof(struct genfs));
5253 		if (!newgenfs) {
5254 			yyerror("out of memory");
5255 			return -1;
5256 		}
5257 		memset(newgenfs, 0, sizeof(struct genfs));
5258 		newgenfs->fstype = fstype;
5259 		newgenfs->next = genfs;
5260 		if (genfs_p)
5261 			genfs_p->next = newgenfs;
5262 		else
5263 			policydbp->genfs = newgenfs;
5264 		genfs = newgenfs;
5265 	}
5266 
5267 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5268 	if (!newc) {
5269 		yyerror("out of memory");
5270 		return -1;
5271 	}
5272 	memset(newc, 0, sizeof(ocontext_t));
5273 
5274 	newc->u.name = (char *)queue_remove(id_queue);
5275 	if (!newc->u.name)
5276 		goto fail;
5277 	if (has_type) {
5278 		type = (char *)queue_remove(id_queue);
5279 		if (!type)
5280 			goto fail;
5281 		if (type[1] != 0) {
5282 			yyerror2("invalid type %s", type);
5283 			goto fail;
5284 		}
5285 		switch (type[0]) {
5286 		case 'b':
5287 			newc->v.sclass = SECCLASS_BLK_FILE;
5288 			break;
5289 		case 'c':
5290 			newc->v.sclass = SECCLASS_CHR_FILE;
5291 			break;
5292 		case 'd':
5293 			newc->v.sclass = SECCLASS_DIR;
5294 			break;
5295 		case 'p':
5296 			newc->v.sclass = SECCLASS_FIFO_FILE;
5297 			break;
5298 		case 'l':
5299 			newc->v.sclass = SECCLASS_LNK_FILE;
5300 			break;
5301 		case 's':
5302 			newc->v.sclass = SECCLASS_SOCK_FILE;
5303 			break;
5304 		case '-':
5305 			newc->v.sclass = SECCLASS_FILE;
5306 			break;
5307 		default:
5308 			yyerror2("invalid type %s", type);
5309 			goto fail;
5310 		}
5311 	}
5312 	if (parse_security_context(&newc->context[0]))
5313 		goto fail;
5314 
5315 	head = genfs->head;
5316 
5317 	for (p = NULL, c = head; c; p = c, c = c->next) {
5318 		if (!strcmp(newc->u.name, c->u.name) &&
5319 		    (!newc->v.sclass || !c->v.sclass
5320 		     || newc->v.sclass == c->v.sclass)) {
5321 			yyerror2("duplicate entry for genfs entry (%s, %s)",
5322 				 fstype, newc->u.name);
5323 			goto fail;
5324 		}
5325 		len = strlen(newc->u.name);
5326 		len2 = strlen(c->u.name);
5327 		if (len > len2)
5328 			break;
5329 	}
5330 
5331 	newc->next = c;
5332 	if (p)
5333 		p->next = newc;
5334 	else
5335 		genfs->head = newc;
5336 	return 0;
5337       fail:
5338 	if (type)
5339 		free(type);
5340 	context_destroy(&newc->context[0]);
5341 	if (fstype)
5342 		free(fstype);
5343 	if (newc->u.name)
5344 		free(newc->u.name);
5345 	free(newc);
5346 	return -1;
5347 }
5348 
define_genfs_context(int has_type)5349 int define_genfs_context(int has_type)
5350 {
5351 	return define_genfs_context_helper(queue_remove(id_queue), has_type);
5352 }
5353 
define_range_trans(int class_specified)5354 int define_range_trans(int class_specified)
5355 {
5356 	char *id;
5357 	level_datum_t *levdatum = 0;
5358 	class_datum_t *cladatum;
5359 	range_trans_rule_t *rule;
5360 	int l, add = 1;
5361 
5362 	if (!mlspol) {
5363 		yyerror("range_transition rule in non-MLS configuration");
5364 		return -1;
5365 	}
5366 
5367 	if (pass == 1) {
5368 		while ((id = queue_remove(id_queue)))
5369 			free(id);
5370 		while ((id = queue_remove(id_queue)))
5371 			free(id);
5372 		if (class_specified)
5373 			while ((id = queue_remove(id_queue)))
5374 				free(id);
5375 		id = queue_remove(id_queue);
5376 		free(id);
5377 		for (l = 0; l < 2; l++) {
5378 			while ((id = queue_remove(id_queue))) {
5379 				free(id);
5380 			}
5381 			id = queue_remove(id_queue);
5382 			if (!id)
5383 				break;
5384 			free(id);
5385 		}
5386 		return 0;
5387 	}
5388 
5389 	rule = malloc(sizeof(struct range_trans_rule));
5390 	if (!rule) {
5391 		yyerror("out of memory");
5392 		return -1;
5393 	}
5394 	range_trans_rule_init(rule);
5395 
5396 	while ((id = queue_remove(id_queue))) {
5397 		if (set_types(&rule->stypes, id, &add, 0))
5398 			goto out;
5399 	}
5400 	add = 1;
5401 	while ((id = queue_remove(id_queue))) {
5402 		if (set_types(&rule->ttypes, id, &add, 0))
5403 			goto out;
5404 	}
5405 
5406 	if (class_specified) {
5407 		if (read_classes(&rule->tclasses))
5408 			goto out;
5409 	} else {
5410 		cladatum = hashtab_search(policydbp->p_classes.table,
5411 		                          "process");
5412 		if (!cladatum) {
5413 			yyerror2("could not find process class for "
5414 			         "legacy range_transition statement");
5415 			goto out;
5416 		}
5417 
5418 		if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE)) {
5419 			yyerror("out of memory");
5420 			goto out;
5421 		}
5422 	}
5423 
5424 	id = (char *)queue_remove(id_queue);
5425 	if (!id) {
5426 		yyerror("no range in range_transition definition?");
5427 		goto out;
5428 	}
5429 	for (l = 0; l < 2; l++) {
5430 		levdatum = hashtab_search(policydbp->p_levels.table, id);
5431 		if (!levdatum) {
5432 			yyerror2("unknown level %s used in range_transition "
5433 			         "definition", id);
5434 			free(id);
5435 			goto out;
5436 		}
5437 		free(id);
5438 
5439 		rule->trange.level[l].sens = levdatum->level->sens;
5440 
5441 		while ((id = queue_remove(id_queue))) {
5442 			if (parse_semantic_categories(id, levdatum,
5443 			                          &rule->trange.level[l].cat)) {
5444 				free(id);
5445 				goto out;
5446 			}
5447 			free(id);
5448 		}
5449 
5450 		id = (char *)queue_remove(id_queue);
5451 		if (!id)
5452 			break;
5453 	}
5454 	if (l == 0) {
5455 		if (mls_semantic_level_cpy(&rule->trange.level[1],
5456 		                           &rule->trange.level[0])) {
5457 			yyerror("out of memory");
5458 			goto out;
5459 		}
5460 	}
5461 
5462 	append_range_trans(rule);
5463 	return 0;
5464 
5465 out:
5466 	range_trans_rule_destroy(rule);
5467 	free(rule);
5468 	return -1;
5469 }
5470 
5471 /* FLASK */
5472