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