• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
3  */
4 
5 /*
6  * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
7  *
8  *	Support for enhanced MLS infrastructure.
9  *
10  * Updated: David Caplan, <dac@tresys.com>
11  *
12  * 	Added conditional policy language extensions
13  *
14  * Updated: Joshua Brindle <jbrindle@tresys.com>
15  *	    Karl MacMillan <kmacmillan@mentalrootkit.com>
16  *          Jason Tang     <jtang@tresys.com>
17  *
18  *	Added support for binary policy modules
19  *
20  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
21  * Copyright (C) 2003 - 2008 Tresys Technology, LLC
22  * Copyright (C) 2007 Red Hat Inc.
23  * 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_ioctl_range {
1878 	uint16_t low;
1879 	uint16_t high;
1880 } av_ioctl_range_t;
1881 
1882 struct av_ioctl_range_list {
1883 	uint8_t omit;
1884 	av_ioctl_range_t range;
1885 	struct av_ioctl_range_list *next;
1886 };
1887 
avrule_sort_ioctls(struct av_ioctl_range_list ** rangehead)1888 static int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead)
1889 {
1890 	struct av_ioctl_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_ioctl_range_list));
1895 		if (sorted == NULL)
1896 			goto error;
1897 		memcpy(sorted, r, sizeof(struct av_ioctl_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_ioctls(struct av_ioctl_range_list ** rangehead)1936 static void avrule_merge_ioctls(struct av_ioctl_range_list **rangehead)
1937 {
1938 	struct av_ioctl_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_ioctls(struct av_ioctl_range_list ** rangehead)1955 static int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
1956 {
1957 	char *id;
1958 	struct av_ioctl_range_list *rnew, *r = NULL;
1959 	uint8_t omit = 0;
1960 
1961 	*rangehead = NULL;
1962 
1963 	/* read in all the ioctl 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_ioctl_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_ioctls(struct av_ioctl_range_list ** rangehead)2009 static int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead)
2010 {
2011 	struct av_ioctl_range_list *rnew, *r, *newhead, *r2;
2012 
2013 	rnew = calloc(1, sizeof(struct av_ioctl_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_ioctl_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_ioctl_ranges(struct av_ioctl_range_list ** rangelist)2057 static int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist)
2058 {
2059 	struct av_ioctl_range_list *rangehead;
2060 	uint8_t omit;
2061 
2062 	/* read in ranges to include and omit */
2063 	if (avrule_read_ioctls(&rangehead))
2064 		return -1;
2065 	if (rangehead == NULL) {
2066 		yyerror("error processing ioctl commands");
2067 		return -1;
2068 	}
2069 	omit = rangehead->omit;
2070 	/* sort and merge the input ioctls */
2071 	if (avrule_sort_ioctls(&rangehead))
2072 		return -1;
2073 	avrule_merge_ioctls(&rangehead);
2074 	/* flip ranges if these are omitted */
2075 	if (omit) {
2076 		if (avrule_omit_ioctls(&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_ioctl_partialdriver(struct av_ioctl_range_list * rangelist,av_extended_perms_t * complete_driver,av_extended_perms_t ** extended_perms)2264 static int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist,
2265 				av_extended_perms_t *complete_driver,
2266 				av_extended_perms_t **extended_perms)
2267 {
2268 	struct av_ioctl_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_ioctl_range_list * rangelist,av_extended_perms_t ** extended_perms)2303 static int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist,
2304 			av_extended_perms_t **extended_perms)
2305 {
2306 	struct av_ioctl_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_ioctl_func(struct av_ioctl_range_list * rangelist,av_extended_perms_t ** extended_perms,unsigned int driver)2345 static int avrule_ioctl_func(struct av_ioctl_range_list *rangelist,
2346 		av_extended_perms_t **extended_perms, unsigned int driver)
2347 {
2348 	struct av_ioctl_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 = AVRULE_XPERMS_IOCTLFUNCTION;
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_ioctl_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_ioctl_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_ioctl_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_ioctl_func(rangelist, &xperms, i))
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_extended_perms(int which)2527 int define_te_avtab_extended_perms(int which)
2528 {
2529 	char *id;
2530 	unsigned int i;
2531 	avrule_t *avrule_template;
2532 	int rc = 0;
2533 
2534 	if (pass == 1) {
2535 		for (i = 0; i < 4; i++) {
2536 			while ((id = queue_remove(id_queue)))
2537 				free(id);
2538 		}
2539 		return 0;
2540 	}
2541 
2542 	/* populate avrule template with source/target/tclass */
2543 	if (define_te_avtab_xperms_helper(which, &avrule_template))
2544 		return -1;
2545 
2546 	id = queue_remove(id_queue);
2547 	if (strcmp(id,"ioctl") == 0) {
2548 		rc = define_te_avtab_ioctl(avrule_template);
2549 	} else {
2550 		yyerror2("only ioctl extended permissions are supported, found %s", id);
2551 		rc = -1;
2552 	}
2553 
2554 	free(id);
2555 	avrule_destroy(avrule_template);
2556 	free(avrule_template);
2557 
2558 	return rc;
2559 }
2560 
2561 #define PERMISSION_MASK(nprim) ((nprim) == PERM_SYMTAB_SIZE ? (~UINT32_C(0)) : ((UINT32_C(1) << (nprim)) - 1))
2562 
define_te_avtab_helper(int which,avrule_t ** rule)2563 static int define_te_avtab_helper(int which, avrule_t ** rule)
2564 {
2565 	char *id;
2566 	class_datum_t *cladatum;
2567 	perm_datum_t *perdatum = NULL;
2568 	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
2569 	ebitmap_t tclasses;
2570 	ebitmap_node_t *node;
2571 	avrule_t *avrule;
2572 	unsigned int i;
2573 	int add = 1, ret = 0;
2574 	int suppress = 0;
2575 
2576 	ebitmap_init(&tclasses);
2577 
2578 	avrule = (avrule_t *) malloc(sizeof(avrule_t));
2579 	if (!avrule) {
2580 		yyerror("memory error");
2581 		ret = -1;
2582 		goto out;
2583 	}
2584 	avrule_init(avrule);
2585 	avrule->specified = which;
2586 	avrule->line = policydb_lineno;
2587 	avrule->source_line = source_lineno;
2588 	avrule->source_filename = strdup(source_file);
2589 	avrule->xperms = NULL;
2590 	if (!avrule->source_filename) {
2591 		yyerror("out of memory");
2592 		return -1;
2593 	}
2594 
2595 
2596 	while ((id = queue_remove(id_queue))) {
2597 		if (set_types
2598 		    (&avrule->stypes, id, &add,
2599 		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
2600 			ret = -1;
2601 			goto out;
2602 		}
2603 	}
2604 	add = 1;
2605 	while ((id = queue_remove(id_queue))) {
2606 		if (strcmp(id, "self") == 0) {
2607 			free(id);
2608 			if (add == 0 && which != AVRULE_NEVERALLOW) {
2609 				yyerror("-self is only supported in neverallow and neverallowxperm rules");
2610 				ret = -1;
2611 				goto out;
2612 			}
2613 			avrule->flags |= (add ? RULE_SELF : RULE_NOTSELF);
2614 			if ((avrule->flags & RULE_SELF) && (avrule->flags & RULE_NOTSELF)) {
2615 				yyerror("self and -self are mutual exclusive");
2616 				ret = -1;
2617 				goto out;
2618 			}
2619 			continue;
2620 		}
2621 		if (set_types
2622 		    (&avrule->ttypes, id, &add,
2623 		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
2624 			ret = -1;
2625 			goto out;
2626 		}
2627 	}
2628 
2629 	if ((avrule->ttypes.flags & TYPE_COMP)) {
2630 		if (avrule->flags & RULE_NOTSELF) {
2631 			yyerror("-self is not supported in complements");
2632 			ret = -1;
2633 			goto out;
2634 		}
2635 		if (avrule->flags & RULE_SELF) {
2636 			avrule->flags &= ~RULE_SELF;
2637 			avrule->flags |= RULE_NOTSELF;
2638 		}
2639 	}
2640 
2641 	ret = read_classes(&tclasses);
2642 	if (ret)
2643 		goto out;
2644 
2645 	perms = NULL;
2646 	ebitmap_for_each_positive_bit(&tclasses, node, i) {
2647 		cur_perms =
2648 		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2649 		if (!cur_perms) {
2650 			yyerror("out of memory");
2651 			ret = -1;
2652 			goto out;
2653 		}
2654 		class_perm_node_init(cur_perms);
2655 		cur_perms->tclass = i + 1;
2656 		if (!perms)
2657 			perms = cur_perms;
2658 		if (tail)
2659 			tail->next = cur_perms;
2660 		tail = cur_perms;
2661 	}
2662 
2663 	while ((id = queue_remove(id_queue))) {
2664 		cur_perms = perms;
2665 		ebitmap_for_each_positive_bit(&tclasses, node, i) {
2666 			cladatum = policydbp->class_val_to_struct[i];
2667 
2668 			if (strcmp(id, "*") == 0) {
2669 				/* set all declared permissions in the class */
2670 				cur_perms->data = PERMISSION_MASK(cladatum->permissions.nprim);
2671 				goto next;
2672 			}
2673 
2674 			if (strcmp(id, "~") == 0) {
2675 				/* complement the set */
2676 				if (which == AVRULE_DONTAUDIT)
2677 					yywarn("dontaudit rule with a ~?");
2678 				cur_perms->data = ~cur_perms->data & PERMISSION_MASK(cladatum->permissions.nprim);
2679 				if (cur_perms->data == 0) {
2680 					class_perm_node_t *tmp = cur_perms;
2681 					yywarn("omitting avrule with no permission set");
2682 					if (perms == cur_perms)
2683 						perms = cur_perms->next;
2684 					cur_perms = cur_perms->next;
2685 					free(tmp);
2686 					continue;
2687 				}
2688 				goto next;
2689 			}
2690 
2691 			perdatum =
2692 			    hashtab_search(cladatum->permissions.table, id);
2693 			if (!perdatum) {
2694 				if (cladatum->comdatum) {
2695 					perdatum =
2696 					    hashtab_search(cladatum->comdatum->
2697 							   permissions.table,
2698 							   id);
2699 				}
2700 			}
2701 			if (!perdatum) {
2702 				if (!suppress)
2703 					yyerror2("permission %s is not defined"
2704 					     " for class %s", id,
2705 					     policydbp->p_class_val_to_name[i]);
2706 				continue;
2707 			} else
2708 			    if (!is_perm_in_scope
2709 				(id, policydbp->p_class_val_to_name[i])) {
2710 				if (!suppress) {
2711 					yyerror2("permission %s of class %s is"
2712 					     " not within scope", id,
2713 					     policydbp->p_class_val_to_name[i]);
2714 				}
2715 				continue;
2716 			} else {
2717 				cur_perms->data |= UINT32_C(1) << (perdatum->s.value - 1);
2718 			}
2719 		      next:
2720 			cur_perms = cur_perms->next;
2721 		}
2722 
2723 		free(id);
2724 	}
2725 
2726 	avrule->perms = perms;
2727 	*rule = avrule;
2728 
2729       out:
2730 	if (ret) {
2731 		avrule_destroy(avrule);
2732 		free(avrule);
2733 	}
2734 
2735 	ebitmap_destroy(&tclasses);
2736 
2737 	return ret;
2738 
2739 }
2740 
define_cond_te_avtab(int which)2741 avrule_t *define_cond_te_avtab(int which)
2742 {
2743 	char *id;
2744 	avrule_t *avrule;
2745 	int i;
2746 
2747 	if (pass == 1) {
2748 		for (i = 0; i < 4; i++) {
2749 			while ((id = queue_remove(id_queue)))
2750 				free(id);
2751 		}
2752 		return (avrule_t *) 1;	/* any non-NULL value */
2753 	}
2754 
2755 	if (define_te_avtab_helper(which, &avrule))
2756 		return COND_ERR;
2757 
2758 	return avrule;
2759 }
2760 
define_te_avtab(int which)2761 int define_te_avtab(int which)
2762 {
2763 	char *id;
2764 	avrule_t *avrule;
2765 	int i;
2766 
2767 	if (pass == 1) {
2768 		for (i = 0; i < 4; i++) {
2769 			while ((id = queue_remove(id_queue)))
2770 				free(id);
2771 		}
2772 		return 0;
2773 	}
2774 
2775 	if (define_te_avtab_helper(which, &avrule))
2776 		return -1;
2777 
2778 	/* append this avrule to the end of the current rules list */
2779 	append_avrule(avrule);
2780 	return 0;
2781 }
2782 
2783 /* The role-types rule is no longer used to declare regular role or
2784  * role attribute, but solely aimed for declaring role-types associations.
2785  */
define_role_types(void)2786 int define_role_types(void)
2787 {
2788 	role_datum_t *role;
2789 	char *id;
2790 	int add = 1;
2791 
2792 	if (pass == 1) {
2793 		while ((id = queue_remove(id_queue)))
2794 			free(id);
2795 		return 0;
2796 	}
2797 
2798 	id = (char *)queue_remove(id_queue);
2799 	if (!id) {
2800 		yyerror("no role name for role-types rule?");
2801 		return -1;
2802 	}
2803 
2804 	if (!is_id_in_scope(SYM_ROLES, id)) {
2805 		yyerror2("role %s is not within scope", id);
2806 		free(id);
2807 		return -1;
2808 	}
2809 
2810 	role = hashtab_search(policydbp->p_roles.table, id);
2811 	if (!role) {
2812 		yyerror2("unknown role %s", id);
2813 		free(id);
2814 		return -1;
2815 	}
2816 	role = get_local_role(id, role->s.value, (role->flavor == ROLE_ATTRIB));
2817 
2818 	while ((id = queue_remove(id_queue))) {
2819 		if (set_types(&role->types, id, &add, 0))
2820 			return -1;
2821 	}
2822 
2823 	return 0;
2824 }
2825 
define_attrib_role(void)2826 int define_attrib_role(void)
2827 {
2828 	if (pass == 2) {
2829 		free(queue_remove(id_queue));
2830 		return 0;
2831 	}
2832 
2833 	/* Declare a role attribute */
2834 	if (declare_role(TRUE) == NULL)
2835 		return -1;
2836 
2837 	return 0;
2838 }
2839 
define_role_attr(void)2840 int define_role_attr(void)
2841 {
2842 	char *id;
2843 	role_datum_t *r, *attr;
2844 
2845 	if (pass == 2) {
2846 		while ((id = queue_remove(id_queue)))
2847 			free(id);
2848 		return 0;
2849 	}
2850 
2851 	/* Declare a regular role */
2852 	if ((r = declare_role(FALSE)) == NULL)
2853 		return -1;
2854 
2855 	while ((id = queue_remove(id_queue))) {
2856 		if (!is_id_in_scope(SYM_ROLES, id)) {
2857 			yyerror2("attribute %s is not within scope", id);
2858 			free(id);
2859 			return -1;
2860 		}
2861 		attr = hashtab_search(policydbp->p_roles.table, id);
2862 		if (!attr) {
2863 			/* treat it as a fatal error */
2864 			yyerror2("role attribute %s is not declared", id);
2865 			free(id);
2866 			return -1;
2867 		}
2868 
2869 		if (attr->flavor != ROLE_ATTRIB) {
2870 			yyerror2("%s is a regular role, not an attribute", id);
2871 			free(id);
2872 			return -1;
2873 		}
2874 
2875 		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2876 			yyerror("Out of memory!");
2877 			return -1;
2878 		}
2879 
2880 		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2881 			yyerror("out of memory");
2882 			return -1;
2883 		}
2884 	}
2885 
2886 	return 0;
2887 }
2888 
define_roleattribute(void)2889 int define_roleattribute(void)
2890 {
2891 	char *id;
2892 	role_datum_t *r, *attr;
2893 
2894 	if (pass == 2) {
2895 		while ((id = queue_remove(id_queue)))
2896 			free(id);
2897 		return 0;
2898 	}
2899 
2900 	id = (char *)queue_remove(id_queue);
2901 	if (!id) {
2902 		yyerror("no role name for roleattribute definition?");
2903 		return -1;
2904 	}
2905 
2906 	if (!is_id_in_scope(SYM_ROLES, id)) {
2907 		yyerror2("role %s is not within scope", id);
2908 		free(id);
2909 		return -1;
2910 	}
2911 	r = hashtab_search(policydbp->p_roles.table, id);
2912 	/* We support adding one role attribute into another */
2913 	if (!r) {
2914 		yyerror2("unknown role %s", id);
2915 		free(id);
2916 		return -1;
2917 	}
2918 	free(id);
2919 
2920 	while ((id = queue_remove(id_queue))) {
2921 		if (!is_id_in_scope(SYM_ROLES, id)) {
2922 			yyerror2("attribute %s is not within scope", id);
2923 			free(id);
2924 			return -1;
2925 		}
2926 		attr = hashtab_search(policydbp->p_roles.table, id);
2927 		if (!attr) {
2928 			/* treat it as a fatal error */
2929 			yyerror2("role attribute %s is not declared", id);
2930 			free(id);
2931 			return -1;
2932 		}
2933 
2934 		if (attr->flavor != ROLE_ATTRIB) {
2935 			yyerror2("%s is a regular role, not an attribute", id);
2936 			free(id);
2937 			return -1;
2938 		}
2939 
2940 		if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2941 			yyerror("Out of memory!");
2942 			return -1;
2943 		}
2944 
2945 		if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2946 			yyerror("out of memory");
2947 			return -1;
2948 		}
2949 	}
2950 
2951 	return 0;
2952 }
2953 
role_val_to_name_helper(hashtab_key_t key,hashtab_datum_t datum,void * p)2954 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
2955 				   void *p)
2956 {
2957 	struct val_to_name *v = p;
2958 	role_datum_t *roldatum;
2959 
2960 	roldatum = (role_datum_t *) datum;
2961 
2962 	if (v->val == roldatum->s.value) {
2963 		v->name = key;
2964 		return 1;
2965 	}
2966 
2967 	return 0;
2968 }
2969 
role_val_to_name(unsigned int val)2970 static char *role_val_to_name(unsigned int val)
2971 {
2972 	struct val_to_name v;
2973 	int rc;
2974 
2975 	v.val = val;
2976 	rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2977 	if (rc)
2978 		return v.name;
2979 	return NULL;
2980 }
2981 
set_roles(role_set_t * set,char * id)2982 static int set_roles(role_set_t * set, char *id)
2983 {
2984 	role_datum_t *r;
2985 
2986 	if (strcmp(id, "*") == 0) {
2987 		free(id);
2988 		yyerror("* is not allowed for role sets");
2989 		return -1;
2990 	}
2991 
2992 	if (strcmp(id, "~") == 0) {
2993 		free(id);
2994 		yyerror("~ is not allowed for role sets");
2995 		return -1;
2996 	}
2997 	if (!is_id_in_scope(SYM_ROLES, id)) {
2998 		yyerror2("role %s is not within scope", id);
2999 		free(id);
3000 		return -1;
3001 	}
3002 	r = hashtab_search(policydbp->p_roles.table, id);
3003 	if (!r) {
3004 		yyerror2("unknown role %s", id);
3005 		free(id);
3006 		return -1;
3007 	}
3008 
3009 	if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
3010 		yyerror("out of memory");
3011 		free(id);
3012 		return -1;
3013 	}
3014 	free(id);
3015 	return 0;
3016 }
3017 
define_role_trans(int class_specified)3018 int define_role_trans(int class_specified)
3019 {
3020 	char *id;
3021 	role_datum_t *role;
3022 	role_set_t roles;
3023 	type_set_t types;
3024 	class_datum_t *cladatum;
3025 	ebitmap_t e_types, e_roles, e_classes;
3026 	ebitmap_node_t *tnode, *rnode, *cnode;
3027 	struct role_trans *tr = NULL;
3028 	struct role_trans_rule *rule = NULL;
3029 	unsigned int i, j, k;
3030 	int add = 1;
3031 
3032 	if (pass == 1) {
3033 		while ((id = queue_remove(id_queue)))
3034 			free(id);
3035 		while ((id = queue_remove(id_queue)))
3036 			free(id);
3037 		if (class_specified)
3038 			while ((id = queue_remove(id_queue)))
3039 				free(id);
3040 		id = queue_remove(id_queue);
3041 		free(id);
3042 		return 0;
3043 	}
3044 
3045 	role_set_init(&roles);
3046 	ebitmap_init(&e_roles);
3047 	type_set_init(&types);
3048 	ebitmap_init(&e_types);
3049 	ebitmap_init(&e_classes);
3050 
3051 	while ((id = queue_remove(id_queue))) {
3052 		if (set_roles(&roles, id))
3053 			return -1;
3054 	}
3055 	add = 1;
3056 	while ((id = queue_remove(id_queue))) {
3057 		if (set_types(&types, id, &add, 0))
3058 			return -1;
3059 	}
3060 
3061 	if (class_specified) {
3062 		if (read_classes(&e_classes))
3063 			return -1;
3064 	} else {
3065 		cladatum = hashtab_search(policydbp->p_classes.table,
3066 					  "process");
3067 		if (!cladatum) {
3068 			yyerror2("could not find process class for "
3069 				 "legacy role_transition statement");
3070 			return -1;
3071 		}
3072 
3073 		if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) {
3074 			yyerror("out of memory");
3075 			return -1;
3076 		}
3077 	}
3078 
3079 	id = (char *)queue_remove(id_queue);
3080 	if (!id) {
3081 		yyerror("no new role in transition definition?");
3082 		goto bad;
3083 	}
3084 	if (!is_id_in_scope(SYM_ROLES, id)) {
3085 		yyerror2("role %s is not within scope", id);
3086 		free(id);
3087 		goto bad;
3088 	}
3089 	role = hashtab_search(policydbp->p_roles.table, id);
3090 	if (!role) {
3091 		yyerror2("unknown role %s used in transition definition", id);
3092 		free(id);
3093 		goto bad;
3094 	}
3095 
3096 	if (role->flavor != ROLE_ROLE) {
3097 		yyerror2("the new role %s must be a regular role", id);
3098 		free(id);
3099 		goto bad;
3100 	}
3101 	free(id);
3102 
3103 	/* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
3104 	if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
3105 		goto bad;
3106 
3107 	if (type_set_expand(&types, &e_types, policydbp, 1))
3108 		goto bad;
3109 
3110 	ebitmap_for_each_positive_bit(&e_roles, rnode, i) {
3111 		ebitmap_for_each_positive_bit(&e_types, tnode, j) {
3112 			ebitmap_for_each_positive_bit(&e_classes, cnode, k) {
3113 				for (tr = policydbp->role_tr; tr;
3114 				     tr = tr->next) {
3115 					if (tr->role == (i + 1) &&
3116 					    tr->type == (j + 1) &&
3117 					    tr->tclass == (k + 1)) {
3118 						yyerror2("duplicate role "
3119 							 "transition for "
3120 							 "(%s,%s,%s)",
3121 							 role_val_to_name(i+1),
3122 							 policydbp->p_type_val_to_name[j],
3123 							 policydbp->p_class_val_to_name[k]);
3124 						goto bad;
3125 					}
3126 				}
3127 
3128 				tr = malloc(sizeof(struct role_trans));
3129 				if (!tr) {
3130 					yyerror("out of memory");
3131 					return -1;
3132 				}
3133 				memset(tr, 0, sizeof(struct role_trans));
3134 				tr->role = i + 1;
3135 				tr->type = j + 1;
3136 				tr->tclass = k + 1;
3137 				tr->new_role = role->s.value;
3138 				tr->next = policydbp->role_tr;
3139 				policydbp->role_tr = tr;
3140 			}
3141 		}
3142 	}
3143 	/* Now add the real rule */
3144 	rule = malloc(sizeof(struct role_trans_rule));
3145 	if (!rule) {
3146 		yyerror("out of memory");
3147 		return -1;
3148 	}
3149 	memset(rule, 0, sizeof(struct role_trans_rule));
3150 	rule->roles = roles;
3151 	rule->types = types;
3152 	rule->classes = e_classes;
3153 	rule->new_role = role->s.value;
3154 
3155 	append_role_trans(rule);
3156 
3157 	ebitmap_destroy(&e_roles);
3158 	ebitmap_destroy(&e_types);
3159 
3160 	return 0;
3161 
3162       bad:
3163 	return -1;
3164 }
3165 
define_role_allow(void)3166 int define_role_allow(void)
3167 {
3168 	char *id;
3169 	struct role_allow_rule *ra = 0;
3170 
3171 	if (pass == 1) {
3172 		while ((id = queue_remove(id_queue)))
3173 			free(id);
3174 		while ((id = queue_remove(id_queue)))
3175 			free(id);
3176 		return 0;
3177 	}
3178 
3179 	ra = malloc(sizeof(role_allow_rule_t));
3180 	if (!ra) {
3181 		yyerror("out of memory");
3182 		return -1;
3183 	}
3184 	role_allow_rule_init(ra);
3185 
3186 	while ((id = queue_remove(id_queue))) {
3187 		if (set_roles(&ra->roles, id)) {
3188 			role_allow_rule_destroy(ra);
3189 			free(ra);
3190 			return -1;
3191 		}
3192 	}
3193 
3194 	while ((id = queue_remove(id_queue))) {
3195 		if (set_roles(&ra->new_roles, id)) {
3196 			role_allow_rule_destroy(ra);
3197 			free(ra);
3198 			return -1;
3199 		}
3200 	}
3201 
3202 	append_role_allow(ra);
3203 	return 0;
3204 }
3205 
define_cond_filename_trans(void)3206 avrule_t *define_cond_filename_trans(void)
3207 {
3208 	yyerror("type transitions with a filename not allowed inside "
3209 		"conditionals");
3210 	return COND_ERR;
3211 }
3212 
define_filename_trans(void)3213 int define_filename_trans(void)
3214 {
3215 	char *id, *name = NULL;
3216 	type_set_t stypes, ttypes;
3217 	ebitmap_t e_stypes, e_ttypes;
3218 	ebitmap_t e_tclasses;
3219 	ebitmap_node_t *snode, *tnode, *cnode;
3220 	filename_trans_rule_t *ftr;
3221 	type_datum_t *typdatum;
3222 	uint32_t otype;
3223 	unsigned int c, s, t;
3224 	int add, self, rc;
3225 
3226 	if (pass == 1) {
3227 		/* stype */
3228 		while ((id = queue_remove(id_queue)))
3229 			free(id);
3230 		/* ttype */
3231 		while ((id = queue_remove(id_queue)))
3232 			free(id);
3233 		/* tclass */
3234 		while ((id = queue_remove(id_queue)))
3235 			free(id);
3236 		/* otype */
3237 		id = queue_remove(id_queue);
3238 		free(id);
3239 		/* name */
3240 		id = queue_remove(id_queue);
3241 		free(id);
3242 		return 0;
3243 	}
3244 
3245 	type_set_init(&stypes);
3246 	type_set_init(&ttypes);
3247 	ebitmap_init(&e_stypes);
3248 	ebitmap_init(&e_ttypes);
3249 	ebitmap_init(&e_tclasses);
3250 
3251 	add = 1;
3252 	while ((id = queue_remove(id_queue))) {
3253 		if (set_types(&stypes, id, &add, 0))
3254 			goto bad;
3255 	}
3256 
3257 	self = 0;
3258 	add = 1;
3259 	while ((id = queue_remove(id_queue))) {
3260 		if (strcmp(id, "self") == 0) {
3261 			free(id);
3262 			if (add == 0) {
3263 				yyerror("-self is not supported");
3264 				goto bad;
3265 			}
3266 			self = 1;
3267 			continue;
3268 		}
3269 		if (set_types(&ttypes, id, &add, 0))
3270 			goto bad;
3271 	}
3272 
3273 	if (read_classes(&e_tclasses))
3274 		goto bad;
3275 
3276 	id = (char *)queue_remove(id_queue);
3277 	if (!id) {
3278 		yyerror("no otype in transition definition?");
3279 		goto bad;
3280 	}
3281 	if (!is_id_in_scope(SYM_TYPES, id)) {
3282 		yyerror2("type %s is not within scope", id);
3283 		free(id);
3284 		goto bad;
3285 	}
3286 	typdatum = hashtab_search(policydbp->p_types.table, id);
3287 	if (!typdatum) {
3288 		yyerror2("unknown type %s used in transition definition", id);
3289 		free(id);
3290 		goto bad;
3291 	}
3292 	free(id);
3293 	otype = typdatum->s.value;
3294 
3295 	name = queue_remove(id_queue);
3296 	if (!name) {
3297 		yyerror("no pathname specified in filename_trans definition?");
3298 		goto bad;
3299 	}
3300 
3301 	/* We expand the class set into separate rules.  We expand the types
3302 	 * just to make sure there are not duplicates.  They will get turned
3303 	 * into separate rules later */
3304 	if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
3305 		goto bad;
3306 
3307 	if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
3308 		goto bad;
3309 
3310 	ebitmap_for_each_positive_bit(&e_tclasses, cnode, c) {
3311 		ebitmap_for_each_positive_bit(&e_stypes, snode, s) {
3312 			ebitmap_for_each_positive_bit(&e_ttypes, tnode, t) {
3313 				rc = policydb_filetrans_insert(
3314 					policydbp, s+1, t+1, c+1, name,
3315 					NULL, otype, NULL
3316 				);
3317 				if (rc != SEPOL_OK) {
3318 					if (rc == SEPOL_EEXIST) {
3319 						yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
3320 							name,
3321 							policydbp->p_type_val_to_name[s],
3322 							policydbp->p_type_val_to_name[t],
3323 							policydbp->p_class_val_to_name[c]);
3324 						goto bad;
3325 					}
3326 					yyerror("out of memory");
3327 					goto bad;
3328 				}
3329 			}
3330 			if (self) {
3331 				rc = policydb_filetrans_insert(
3332 					policydbp, s+1, s+1, c+1, name,
3333 					NULL, otype, NULL
3334 				);
3335 				if (rc != SEPOL_OK) {
3336 					if (rc == SEPOL_EEXIST) {
3337 						yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
3338 							name,
3339 							policydbp->p_type_val_to_name[s],
3340 							policydbp->p_type_val_to_name[s],
3341 							policydbp->p_class_val_to_name[c]);
3342 						goto bad;
3343 					}
3344 					yyerror("out of memory");
3345 					goto bad;
3346 				}
3347 			}
3348 		}
3349 
3350 		/* Now add the real rule since we didn't find any duplicates */
3351 		ftr = malloc(sizeof(*ftr));
3352 		if (!ftr) {
3353 			yyerror("out of memory");
3354 			goto bad;
3355 		}
3356 		filename_trans_rule_init(ftr);
3357 		append_filename_trans(ftr);
3358 
3359 		ftr->name = strdup(name);
3360 		if (type_set_cpy(&ftr->stypes, &stypes)) {
3361 			yyerror("out of memory");
3362 			goto bad;
3363 		}
3364 		if (type_set_cpy(&ftr->ttypes, &ttypes)) {
3365 			yyerror("out of memory");
3366 			goto bad;
3367 		}
3368 		ftr->tclass = c + 1;
3369 		ftr->otype = otype;
3370 		ftr->flags = self ? RULE_SELF : 0;
3371 	}
3372 
3373 	free(name);
3374 	ebitmap_destroy(&e_stypes);
3375 	ebitmap_destroy(&e_ttypes);
3376 	ebitmap_destroy(&e_tclasses);
3377 	type_set_destroy(&stypes);
3378 	type_set_destroy(&ttypes);
3379 
3380 	return 0;
3381 
3382 bad:
3383 	free(name);
3384 	ebitmap_destroy(&e_stypes);
3385 	ebitmap_destroy(&e_ttypes);
3386 	ebitmap_destroy(&e_tclasses);
3387 	type_set_destroy(&stypes);
3388 	type_set_destroy(&ttypes);
3389 	return -1;
3390 }
3391 
constraint_expr_clone(const constraint_expr_t * expr)3392 static constraint_expr_t *constraint_expr_clone(const constraint_expr_t * expr)
3393 {
3394 	constraint_expr_t *h = NULL, *l = NULL, *newe;
3395 	const constraint_expr_t *e;
3396 	for (e = expr; e; e = e->next) {
3397 		newe = malloc(sizeof(*newe));
3398 		if (!newe)
3399 			goto oom;
3400 		if (constraint_expr_init(newe) == -1) {
3401 			free(newe);
3402 			goto oom;
3403 		}
3404 		if (l)
3405 			l->next = newe;
3406 		else
3407 			h = newe;
3408 		l = newe;
3409 		newe->expr_type = e->expr_type;
3410 		newe->attr = e->attr;
3411 		newe->op = e->op;
3412 		if (newe->expr_type == CEXPR_NAMES) {
3413 			if (newe->attr & CEXPR_TYPE) {
3414 				if (type_set_cpy
3415 				    (newe->type_names, e->type_names))
3416 					goto oom;
3417 			} else {
3418 				if (ebitmap_cpy(&newe->names, &e->names))
3419 					goto oom;
3420 			}
3421 		}
3422 	}
3423 
3424 	return h;
3425       oom:
3426 	constraint_expr_destroy(h);
3427 	return NULL;
3428 }
3429 
define_constraint(constraint_expr_t * expr)3430 int define_constraint(constraint_expr_t * expr)
3431 {
3432 	struct constraint_node *node;
3433 	char *id;
3434 	class_datum_t *cladatum;
3435 	perm_datum_t *perdatum;
3436 	ebitmap_t classmap;
3437 	ebitmap_node_t *enode;
3438 	constraint_expr_t *e;
3439 	unsigned int i;
3440 	int depth;
3441 	unsigned char useexpr = 1;
3442 
3443 	if (pass == 1) {
3444 		while ((id = queue_remove(id_queue)))
3445 			free(id);
3446 		while ((id = queue_remove(id_queue)))
3447 			free(id);
3448 		return 0;
3449 	}
3450 
3451 	ebitmap_init(&classmap);
3452 
3453 	depth = -1;
3454 	for (e = expr; e; e = e->next) {
3455 		switch (e->expr_type) {
3456 		case CEXPR_NOT:
3457 			if (depth < 0) {
3458 				yyerror("illegal constraint expression");
3459 				goto bad;
3460 			}
3461 			break;
3462 		case CEXPR_AND:
3463 		case CEXPR_OR:
3464 			if (depth < 1) {
3465 				yyerror("illegal constraint expression");
3466 				goto bad;
3467 			}
3468 			depth--;
3469 			break;
3470 		case CEXPR_ATTR:
3471 		case CEXPR_NAMES:
3472 			if (e->attr & CEXPR_XTARGET) {
3473 				yyerror("illegal constraint expression");
3474 				goto bad;	/* only for validatetrans rules */
3475 			}
3476 			if (depth == (CEXPR_MAXDEPTH - 1)) {
3477 				yyerror("constraint expression is too deep");
3478 				goto bad;
3479 			}
3480 			depth++;
3481 			break;
3482 		default:
3483 			yyerror("illegal constraint expression");
3484 			goto bad;
3485 		}
3486 	}
3487 	if (depth != 0) {
3488 		yyerror("illegal constraint expression");
3489 		goto bad;
3490 	}
3491 
3492 	while ((id = queue_remove(id_queue))) {
3493 		if (!is_id_in_scope(SYM_CLASSES, id)) {
3494 			yyerror2("class %s is not within scope", id);
3495 			free(id);
3496 			goto bad;
3497 		}
3498 		cladatum =
3499 		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3500 						     (hashtab_key_t) id);
3501 		if (!cladatum) {
3502 			yyerror2("class %s is not defined", id);
3503 			free(id);
3504 			goto bad;
3505 		}
3506 		if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
3507 			yyerror("out of memory");
3508 			free(id);
3509 			goto bad;
3510 		}
3511 		node = malloc(sizeof(struct constraint_node));
3512 		if (!node) {
3513 			yyerror("out of memory");
3514 			free(node);
3515 			goto bad;
3516 		}
3517 		memset(node, 0, sizeof(constraint_node_t));
3518 		if (useexpr) {
3519 			node->expr = expr;
3520 			useexpr = 0;
3521 		} else {
3522 			node->expr = constraint_expr_clone(expr);
3523 		}
3524 		if (!node->expr) {
3525 			yyerror("out of memory");
3526 			free(node);
3527 			goto bad;
3528 		}
3529 		node->permissions = 0;
3530 
3531 		node->next = cladatum->constraints;
3532 		cladatum->constraints = node;
3533 
3534 		free(id);
3535 	}
3536 
3537 	while ((id = queue_remove(id_queue))) {
3538 		ebitmap_for_each_positive_bit(&classmap, enode, i) {
3539 			cladatum = policydbp->class_val_to_struct[i];
3540 			node = cladatum->constraints;
3541 
3542 			if (strcmp(id, "*") == 0) {
3543 				node->permissions = PERMISSION_MASK(cladatum->permissions.nprim);
3544 				continue;
3545 			}
3546 
3547 			if (strcmp(id, "~") == 0) {
3548 				node->permissions = ~node->permissions & PERMISSION_MASK(cladatum->permissions.nprim);
3549 				if (node->permissions == 0) {
3550 					yywarn("omitting constraint with no permission set");
3551 					cladatum->constraints = node->next;
3552 					constraint_expr_destroy(node->expr);
3553 					free(node);
3554 				}
3555 				continue;
3556 			}
3557 
3558 			perdatum =
3559 			    (perm_datum_t *) hashtab_search(cladatum->
3560 							    permissions.
3561 							    table,
3562 							    (hashtab_key_t)
3563 							    id);
3564 			if (!perdatum) {
3565 				if (cladatum->comdatum) {
3566 					perdatum =
3567 					    (perm_datum_t *)
3568 					    hashtab_search(cladatum->
3569 							   comdatum->
3570 							   permissions.
3571 							   table,
3572 							   (hashtab_key_t)
3573 							   id);
3574 				}
3575 				if (!perdatum) {
3576 					yyerror2("permission %s is not"
3577 						 " defined for class %s", id, policydbp->p_class_val_to_name[i]);
3578 					free(id);
3579 					goto bad;
3580 				}
3581 			}
3582 			node->permissions |= (UINT32_C(1) << (perdatum->s.value - 1));
3583 		}
3584 		free(id);
3585 	}
3586 
3587 	ebitmap_destroy(&classmap);
3588 
3589 	return 0;
3590 
3591 bad:
3592 	ebitmap_destroy(&classmap);
3593 	if (useexpr)
3594 		constraint_expr_destroy(expr);
3595 
3596 	return -1;
3597 }
3598 
define_validatetrans(constraint_expr_t * expr)3599 int define_validatetrans(constraint_expr_t * expr)
3600 {
3601 	struct constraint_node *node;
3602 	char *id;
3603 	class_datum_t *cladatum;
3604 	ebitmap_t classmap;
3605 	constraint_expr_t *e;
3606 	int depth;
3607 	unsigned char useexpr = 1;
3608 
3609 	if (pass == 1) {
3610 		while ((id = queue_remove(id_queue)))
3611 			free(id);
3612 		return 0;
3613 	}
3614 
3615 	ebitmap_init(&classmap);
3616 
3617 	depth = -1;
3618 	for (e = expr; e; e = e->next) {
3619 		switch (e->expr_type) {
3620 		case CEXPR_NOT:
3621 			if (depth < 0) {
3622 				yyerror("illegal validatetrans expression");
3623 				goto bad;
3624 			}
3625 			break;
3626 		case CEXPR_AND:
3627 		case CEXPR_OR:
3628 			if (depth < 1) {
3629 				yyerror("illegal validatetrans expression");
3630 				goto bad;
3631 			}
3632 			depth--;
3633 			break;
3634 		case CEXPR_ATTR:
3635 		case CEXPR_NAMES:
3636 			if (depth == (CEXPR_MAXDEPTH - 1)) {
3637 				yyerror("validatetrans expression is too deep");
3638 				goto bad;
3639 			}
3640 			depth++;
3641 			break;
3642 		default:
3643 			yyerror("illegal validatetrans expression");
3644 			goto bad;
3645 		}
3646 	}
3647 	if (depth != 0) {
3648 		yyerror("illegal validatetrans expression");
3649 		goto bad;
3650 	}
3651 
3652 	while ((id = queue_remove(id_queue))) {
3653 		if (!is_id_in_scope(SYM_CLASSES, id)) {
3654 			yyerror2("class %s is not within scope", id);
3655 			free(id);
3656 			goto bad;
3657 		}
3658 		cladatum =
3659 		    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3660 						     (hashtab_key_t) id);
3661 		if (!cladatum) {
3662 			yyerror2("class %s is not defined", id);
3663 			free(id);
3664 			goto bad;
3665 		}
3666 		if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
3667 			yyerror("out of memory");
3668 			free(id);
3669 			goto bad;
3670 		}
3671 
3672 		node = malloc(sizeof(struct constraint_node));
3673 		if (!node) {
3674 			yyerror("out of memory");
3675 			free(id);
3676 			goto bad;
3677 		}
3678 		memset(node, 0, sizeof(constraint_node_t));
3679 		if (useexpr) {
3680 			node->expr = expr;
3681 			useexpr = 0;
3682 		} else {
3683 			node->expr = constraint_expr_clone(expr);
3684 		}
3685 		node->permissions = 0;
3686 
3687 		node->next = cladatum->validatetrans;
3688 		cladatum->validatetrans = node;
3689 
3690 		free(id);
3691 	}
3692 
3693 	ebitmap_destroy(&classmap);
3694 
3695 	return 0;
3696 
3697 bad:
3698 	ebitmap_destroy(&classmap);
3699 	if (useexpr)
3700 		constraint_expr_destroy(expr);
3701 
3702 	return -1;
3703 }
3704 
define_cexpr(uint32_t expr_type,uintptr_t arg1,uintptr_t arg2)3705 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
3706 {
3707 	struct constraint_expr *expr, *e1 = NULL, *e2;
3708 	user_datum_t *user;
3709 	role_datum_t *role;
3710 	ebitmap_t negset;
3711 	char *id;
3712 	uint32_t val;
3713 	int add = 1;
3714 
3715 	if (pass == 1) {
3716 		if (expr_type == CEXPR_NAMES) {
3717 			while ((id = queue_remove(id_queue)))
3718 				free(id);
3719 		}
3720 		return 1;	/* any non-NULL value */
3721 	}
3722 
3723 	if ((expr = malloc(sizeof(*expr))) == NULL ||
3724 	    constraint_expr_init(expr) == -1) {
3725 		yyerror("out of memory");
3726 		free(expr);
3727 		return 0;
3728 	}
3729 	expr->expr_type = expr_type;
3730 
3731 	switch (expr_type) {
3732 	case CEXPR_NOT:
3733 		e1 = NULL;
3734 		e2 = (struct constraint_expr *)arg1;
3735 		while (e2) {
3736 			e1 = e2;
3737 			e2 = e2->next;
3738 		}
3739 		if (!e1 || e1->next) {
3740 			yyerror("illegal constraint expression");
3741 			constraint_expr_destroy(expr);
3742 			return 0;
3743 		}
3744 		e1->next = expr;
3745 		return arg1;
3746 	case CEXPR_AND:
3747 	case CEXPR_OR:
3748 		e1 = NULL;
3749 		e2 = (struct constraint_expr *)arg1;
3750 		while (e2) {
3751 			e1 = e2;
3752 			e2 = e2->next;
3753 		}
3754 		if (!e1 || e1->next) {
3755 			yyerror("illegal constraint expression");
3756 			constraint_expr_destroy(expr);
3757 			return 0;
3758 		}
3759 		e1->next = (struct constraint_expr *)arg2;
3760 
3761 		e1 = NULL;
3762 		e2 = (struct constraint_expr *)arg2;
3763 		while (e2) {
3764 			e1 = e2;
3765 			e2 = e2->next;
3766 		}
3767 		if (!e1 || e1->next) {
3768 			yyerror("illegal constraint expression");
3769 			constraint_expr_destroy(expr);
3770 			return 0;
3771 		}
3772 		e1->next = expr;
3773 		return arg1;
3774 	case CEXPR_ATTR:
3775 		expr->attr = arg1;
3776 		expr->op = arg2;
3777 		return (uintptr_t) expr;
3778 	case CEXPR_NAMES:
3779 		add = 1;
3780 		expr->attr = arg1;
3781 		expr->op = arg2;
3782 		ebitmap_init(&negset);
3783 		while ((id = (char *)queue_remove(id_queue))) {
3784 			if (expr->attr & CEXPR_USER) {
3785 				if (!is_id_in_scope(SYM_USERS, id)) {
3786 					yyerror2("user %s is not within scope",
3787 						 id);
3788 					free(id);
3789 					constraint_expr_destroy(expr);
3790 					return 0;
3791 				}
3792 				user =
3793 				    (user_datum_t *) hashtab_search(policydbp->
3794 								    p_users.
3795 								    table,
3796 								    (hashtab_key_t)
3797 								    id);
3798 				if (!user) {
3799 					yyerror2("unknown user %s", id);
3800 					free(id);
3801 					constraint_expr_destroy(expr);
3802 					return 0;
3803 				}
3804 				val = user->s.value;
3805 			} else if (expr->attr & CEXPR_ROLE) {
3806 				if (!is_id_in_scope(SYM_ROLES, id)) {
3807 					yyerror2("role %s is not within scope",
3808 						 id);
3809 					constraint_expr_destroy(expr);
3810 					free(id);
3811 					return 0;
3812 				}
3813 				role =
3814 				    (role_datum_t *) hashtab_search(policydbp->
3815 								    p_roles.
3816 								    table,
3817 								    (hashtab_key_t)
3818 								    id);
3819 				if (!role) {
3820 					yyerror2("unknown role %s", id);
3821 					constraint_expr_destroy(expr);
3822 					free(id);
3823 					return 0;
3824 				}
3825 				val = role->s.value;
3826 			} else if (expr->attr & CEXPR_TYPE) {
3827 				if (set_types(expr->type_names, id, &add, 0)) {
3828 					constraint_expr_destroy(expr);
3829 					return 0;
3830 				}
3831 				continue;
3832 			} else {
3833 				yyerror("invalid constraint expression");
3834 				constraint_expr_destroy(expr);
3835 				free(id);
3836 				return 0;
3837 			}
3838 			if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3839 				yyerror("out of memory");
3840 				ebitmap_destroy(&expr->names);
3841 				free(id);
3842 				constraint_expr_destroy(expr);
3843 				return 0;
3844 			}
3845 			free(id);
3846 		}
3847 		ebitmap_destroy(&negset);
3848 		return (uintptr_t) expr;
3849 	default:
3850 		break;
3851 	}
3852 
3853 	yyerror("invalid constraint expression");
3854 	constraint_expr_destroy(expr);
3855 	return 0;
3856 }
3857 
define_conditional(cond_expr_t * expr,avrule_t * t_list,avrule_t * f_list)3858 int define_conditional(cond_expr_t * expr, avrule_t * t_list, avrule_t * f_list)
3859 {
3860 	cond_expr_t *e;
3861 	int depth, booleans, tunables;
3862 	cond_node_t cn, *cn_old;
3863 	const cond_bool_datum_t *bool_var;
3864 
3865 	/* expression cannot be NULL */
3866 	if (!expr) {
3867 		yyerror("illegal conditional expression");
3868 		return -1;
3869 	}
3870 	if (!t_list) {
3871 		if (!f_list) {
3872 			/* empty is fine, destroy expression and return */
3873 			cond_expr_destroy(expr);
3874 			return 0;
3875 		}
3876 		/* Invert */
3877 		t_list = f_list;
3878 		f_list = NULL;
3879 		expr = define_cond_expr(COND_NOT, expr, 0);
3880 		if (!expr) {
3881 			yyerror("unable to invert conditional expression");
3882 			return -1;
3883 		}
3884 	}
3885 
3886 	/* verify expression */
3887 	depth = -1;
3888 	booleans = 0;
3889 	tunables = 0;
3890 	for (e = expr; e; e = e->next) {
3891 		switch (e->expr_type) {
3892 		case COND_NOT:
3893 			if (depth < 0) {
3894 				yyerror
3895 				    ("illegal conditional expression; Bad NOT");
3896 				return -1;
3897 			}
3898 			break;
3899 		case COND_AND:
3900 		case COND_OR:
3901 		case COND_XOR:
3902 		case COND_EQ:
3903 		case COND_NEQ:
3904 			if (depth < 1) {
3905 				yyerror
3906 				    ("illegal conditional expression; Bad binary op");
3907 				return -1;
3908 			}
3909 			depth--;
3910 			break;
3911 		case COND_BOOL:
3912 			if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3913 				yyerror
3914 				    ("conditional expression is like totally too deep");
3915 				return -1;
3916 			}
3917 			depth++;
3918 
3919 			bool_var = policydbp->bool_val_to_struct[e->boolean - 1];
3920 			if (bool_var->flags & COND_BOOL_FLAGS_TUNABLE) {
3921 				tunables = 1;
3922 			} else {
3923 				booleans = 1;
3924 			}
3925 
3926 			break;
3927 		default:
3928 			yyerror("illegal conditional expression");
3929 			return -1;
3930 		}
3931 	}
3932 	if (depth != 0) {
3933 		yyerror("illegal conditional expression");
3934 		return -1;
3935 	}
3936 	if (booleans && tunables) {
3937 		yyerror("illegal conditional expression; Contains boolean and tunable");
3938 		return -1;
3939 	}
3940 
3941 	/*  use tmp conditional node to partially build new node */
3942 	memset(&cn, 0, sizeof(cn));
3943 	cn.expr = expr;
3944 	cn.avtrue_list = t_list;
3945 	cn.avfalse_list = f_list;
3946 
3947 	/* normalize/precompute expression */
3948 	if (cond_normalize_expr(policydbp, &cn) < 0) {
3949 		yyerror("problem normalizing conditional expression");
3950 		return -1;
3951 	}
3952 
3953 	/* get the existing conditional node, or create a new one */
3954 	cn_old = get_current_cond_list(&cn);
3955 	if (!cn_old) {
3956 		return -1;
3957 	}
3958 
3959 	append_cond_list(&cn);
3960 
3961 	/* note that there is no check here for duplicate rules, nor
3962 	 * check that rule already exists in base -- that will be
3963 	 * handled during conditional expansion, in expand.c */
3964 
3965 	cn.avtrue_list = NULL;
3966 	cn.avfalse_list = NULL;
3967 	cond_node_destroy(&cn);
3968 
3969 	return 0;
3970 }
3971 
define_cond_expr(uint32_t expr_type,void * arg1,void * arg2)3972 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3973 {
3974 	struct cond_expr *expr, *e1 = NULL, *e2;
3975 	cond_bool_datum_t *bool_var;
3976 	char *id;
3977 
3978 	/* expressions are handled in the second pass */
3979 	if (pass == 1) {
3980 		if (expr_type == COND_BOOL) {
3981 			while ((id = queue_remove(id_queue))) {
3982 				free(id);
3983 			}
3984 		}
3985 		return (cond_expr_t *) 1;	/* any non-NULL value */
3986 	}
3987 
3988 	/* create a new expression struct */
3989 	expr = malloc(sizeof(struct cond_expr));
3990 	if (!expr) {
3991 		yyerror("out of memory");
3992 		return NULL;
3993 	}
3994 	memset(expr, 0, sizeof(cond_expr_t));
3995 	expr->expr_type = expr_type;
3996 
3997 	/* create the type asked for */
3998 	switch (expr_type) {
3999 	case COND_NOT:
4000 		e1 = NULL;
4001 		e2 = (struct cond_expr *)arg1;
4002 		while (e2) {
4003 			e1 = e2;
4004 			e2 = e2->next;
4005 		}
4006 		if (!e1 || e1->next) {
4007 			yyerror("illegal conditional NOT expression");
4008 			free(expr);
4009 			return NULL;
4010 		}
4011 		e1->next = expr;
4012 		return (struct cond_expr *)arg1;
4013 	case COND_AND:
4014 	case COND_OR:
4015 	case COND_XOR:
4016 	case COND_EQ:
4017 	case COND_NEQ:
4018 		e1 = NULL;
4019 		e2 = (struct cond_expr *)arg1;
4020 		while (e2) {
4021 			e1 = e2;
4022 			e2 = e2->next;
4023 		}
4024 		if (!e1 || e1->next) {
4025 			yyerror
4026 			    ("illegal left side of conditional binary op expression");
4027 			free(expr);
4028 			return NULL;
4029 		}
4030 		e1->next = (struct cond_expr *)arg2;
4031 
4032 		e1 = NULL;
4033 		e2 = (struct cond_expr *)arg2;
4034 		while (e2) {
4035 			e1 = e2;
4036 			e2 = e2->next;
4037 		}
4038 		if (!e1 || e1->next) {
4039 			yyerror
4040 			    ("illegal right side of conditional binary op expression");
4041 			free(expr);
4042 			return NULL;
4043 		}
4044 		e1->next = expr;
4045 		return (struct cond_expr *)arg1;
4046 	case COND_BOOL:
4047 		id = (char *)queue_remove(id_queue);
4048 		if (!id) {
4049 			yyerror("bad conditional; expected boolean id");
4050 			free(id);
4051 			free(expr);
4052 			return NULL;
4053 		}
4054 		if (!is_id_in_scope(SYM_BOOLS, id)) {
4055 			yyerror2("boolean %s is not within scope", id);
4056 			free(id);
4057 			free(expr);
4058 			return NULL;
4059 		}
4060 		bool_var =
4061 		    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
4062 							 table,
4063 							 (hashtab_key_t) id);
4064 		if (!bool_var) {
4065 			yyerror2("unknown boolean %s in conditional expression",
4066 				 id);
4067 			free(expr);
4068 			free(id);
4069 			return NULL;
4070 		}
4071 		expr->boolean = bool_var->s.value;
4072 		free(id);
4073 		return expr;
4074 	default:
4075 		yyerror("illegal conditional expression");
4076 		free(expr);
4077 		return NULL;
4078 	}
4079 }
4080 
set_user_roles(role_set_t * set,char * id)4081 static int set_user_roles(role_set_t * set, char *id)
4082 {
4083 	role_datum_t *r;
4084 
4085 	if (strcmp(id, "*") == 0) {
4086 		free(id);
4087 		yyerror("* is not allowed in user declarations");
4088 		return -1;
4089 	}
4090 
4091 	if (strcmp(id, "~") == 0) {
4092 		free(id);
4093 		yyerror("~ is not allowed in user declarations");
4094 		return -1;
4095 	}
4096 
4097 	if (!is_id_in_scope(SYM_ROLES, id)) {
4098 		yyerror2("role %s is not within scope", id);
4099 		free(id);
4100 		return -1;
4101 	}
4102 	r = hashtab_search(policydbp->p_roles.table, id);
4103 	if (!r) {
4104 		yyerror2("unknown role %s", id);
4105 		free(id);
4106 		return -1;
4107 	}
4108 
4109 	free(id);
4110 	if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE))
4111 		goto oom;
4112 	return 0;
4113       oom:
4114 	yyerror("out of memory");
4115 	return -1;
4116 }
4117 
parse_categories(char * id,level_datum_t * levdatum,ebitmap_t * cats)4118 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
4119 {
4120 	cat_datum_t *cdatum;
4121 	uint32_t range_start, range_end, i;
4122 
4123 	if (id_has_dot(id)) {
4124 		char *id_start = id;
4125 		char *id_end = strchr(id, '.');
4126 
4127 		*(id_end++) = '\0';
4128 
4129 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4130 							(hashtab_key_t)
4131 							id_start);
4132 		if (!cdatum) {
4133 			yyerror2("unknown category %s", id_start);
4134 			return -1;
4135 		}
4136 		range_start = cdatum->s.value - 1;
4137 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4138 							(hashtab_key_t) id_end);
4139 		if (!cdatum) {
4140 			yyerror2("unknown category %s", id_end);
4141 			return -1;
4142 		}
4143 		range_end = cdatum->s.value - 1;
4144 
4145 		if (range_end < range_start) {
4146 			yyerror2("category range %d-%d is invalid", range_start, range_end);
4147 			return -1;
4148 		}
4149 	} else {
4150 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4151 							(hashtab_key_t) id);
4152 		if (!cdatum) {
4153 			yyerror2("unknown category %s", id);
4154 			return -1;
4155 		}
4156 		range_start = range_end = cdatum->s.value - 1;
4157 	}
4158 
4159 	for (i = range_start; i <= range_end; i++) {
4160 		if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
4161 			uint32_t level_value = levdatum->level->sens - 1;
4162 			policydb_index_others(NULL, policydbp, 0);
4163 			yyerror2("category %s can not be associated "
4164 				 "with level %s",
4165 				 policydbp->p_cat_val_to_name[i],
4166 				 policydbp->p_sens_val_to_name[level_value]);
4167 			return -1;
4168 		}
4169 		if (ebitmap_set_bit(cats, i, TRUE)) {
4170 			yyerror("out of memory");
4171 			return -1;
4172 		}
4173 	}
4174 
4175 	return 0;
4176 }
4177 
parse_semantic_categories(char * id,level_datum_t * levdatum,mls_semantic_cat_t ** cats)4178 static int parse_semantic_categories(char *id, level_datum_t * levdatum __attribute__ ((unused)),
4179 				     mls_semantic_cat_t ** cats)
4180 {
4181 	cat_datum_t *cdatum;
4182 	mls_semantic_cat_t *newcat;
4183 	unsigned int range_start, range_end;
4184 
4185 	if (id_has_dot(id)) {
4186 		char *id_start = id;
4187 		char *id_end = strchr(id, '.');
4188 
4189 		*(id_end++) = '\0';
4190 
4191 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4192 							(hashtab_key_t)
4193 							id_start);
4194 		if (!cdatum) {
4195 			yyerror2("unknown category %s", id_start);
4196 			return -1;
4197 		}
4198 		range_start = cdatum->s.value;
4199 
4200 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4201 							(hashtab_key_t) id_end);
4202 		if (!cdatum) {
4203 			yyerror2("unknown category %s", id_end);
4204 			return -1;
4205 		}
4206 		range_end = cdatum->s.value;
4207 	} else {
4208 		cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4209 							(hashtab_key_t) id);
4210 		if (!cdatum) {
4211 			yyerror2("unknown category %s", id);
4212 			return -1;
4213 		}
4214 		range_start = range_end = cdatum->s.value;
4215 	}
4216 
4217 	newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
4218 	if (!newcat) {
4219 		yyerror("out of memory");
4220 		return -1;
4221 	}
4222 
4223 	mls_semantic_cat_init(newcat);
4224 	newcat->next = *cats;
4225 	newcat->low = range_start;
4226 	newcat->high = range_end;
4227 
4228 	*cats = newcat;
4229 
4230 	return 0;
4231 }
4232 
define_user(void)4233 int define_user(void)
4234 {
4235 	char *id;
4236 	user_datum_t *usrdatum;
4237 	level_datum_t *levdatum;
4238 	int l;
4239 
4240 	if (pass == 1) {
4241 		while ((id = queue_remove(id_queue)))
4242 			free(id);
4243 		if (mlspol) {
4244 			while ((id = queue_remove(id_queue)))
4245 				free(id);
4246 			id = queue_remove(id_queue);
4247 			free(id);
4248 			for (l = 0; l < 2; l++) {
4249 				while ((id = queue_remove(id_queue))) {
4250 					free(id);
4251 				}
4252 				id = queue_remove(id_queue);
4253 				if (!id)
4254 					break;
4255 				free(id);
4256 			}
4257 		}
4258 		return 0;
4259 	}
4260 
4261 	if ((usrdatum = declare_user()) == NULL) {
4262 		return -1;
4263 	}
4264 
4265 	while ((id = queue_remove(id_queue))) {
4266 		if (set_user_roles(&usrdatum->roles, id))
4267 			return -1;
4268 	}
4269 
4270 	if (mlspol) {
4271 		id = queue_remove(id_queue);
4272 		if (!id) {
4273 			yyerror("no default level specified for user");
4274 			return -1;
4275 		}
4276 
4277 		levdatum = (level_datum_t *)
4278 		    hashtab_search(policydbp->p_levels.table,
4279 				   (hashtab_key_t) id);
4280 		if (!levdatum) {
4281 			yyerror2("unknown sensitivity %s used in user"
4282 				 " level definition", id);
4283 			free(id);
4284 			return -1;
4285 		}
4286 		free(id);
4287 
4288 		usrdatum->dfltlevel.sens = levdatum->level->sens;
4289 
4290 		while ((id = queue_remove(id_queue))) {
4291 			if (parse_semantic_categories(id, levdatum,
4292 			                            &usrdatum->dfltlevel.cat)) {
4293 				free(id);
4294 				return -1;
4295 			}
4296 			free(id);
4297 		}
4298 
4299 		id = queue_remove(id_queue);
4300 
4301 		for (l = 0; l < 2; l++) {
4302 			levdatum = (level_datum_t *)
4303 			    hashtab_search(policydbp->p_levels.table,
4304 					   (hashtab_key_t) id);
4305 			if (!levdatum) {
4306 				yyerror2("unknown sensitivity %s used in user"
4307 					 " range definition", id);
4308 				free(id);
4309 				return -1;
4310 			}
4311 			free(id);
4312 
4313 			usrdatum->range.level[l].sens = levdatum->level->sens;
4314 
4315 			while ((id = queue_remove(id_queue))) {
4316 				if (parse_semantic_categories(id, levdatum,
4317 				               &usrdatum->range.level[l].cat)) {
4318 					free(id);
4319 					return -1;
4320 				}
4321 				free(id);
4322 			}
4323 
4324 			id = queue_remove(id_queue);
4325 			if (!id)
4326 				break;
4327 		}
4328 
4329 		if (l == 0) {
4330 			if (mls_semantic_level_cpy(&usrdatum->range.level[1],
4331 			                           &usrdatum->range.level[0])) {
4332 				yyerror("out of memory");
4333 				return -1;
4334 			}
4335 		}
4336 	}
4337 	return 0;
4338 }
4339 
parse_security_context(context_struct_t * c)4340 static int parse_security_context(context_struct_t * c)
4341 {
4342 	char *id;
4343 	role_datum_t *role;
4344 	type_datum_t *typdatum;
4345 	user_datum_t *usrdatum;
4346 	level_datum_t *levdatum;
4347 	int l;
4348 
4349 	if (pass == 1) {
4350 		id = queue_remove(id_queue);
4351 		free(id);	/* user  */
4352 		id = queue_remove(id_queue);
4353 		free(id);	/* role  */
4354 		id = queue_remove(id_queue);
4355 		free(id);	/* type  */
4356 		if (mlspol) {
4357 			id = queue_remove(id_queue);
4358 			free(id);
4359 			for (l = 0; l < 2; l++) {
4360 				while ((id = queue_remove(id_queue))) {
4361 					free(id);
4362 				}
4363 				id = queue_remove(id_queue);
4364 				if (!id)
4365 					break;
4366 				free(id);
4367 			}
4368 		}
4369 		return 0;
4370 	}
4371 
4372 	/* check context c to make sure ok to dereference c later */
4373 	if (c == NULL) {
4374 		yyerror("null context pointer!");
4375 		return -1;
4376 	}
4377 
4378 	context_init(c);
4379 
4380 	/* extract the user */
4381 	id = queue_remove(id_queue);
4382 	if (!id) {
4383 		yyerror("no effective user?");
4384 		goto bad;
4385 	}
4386 	if (!is_id_in_scope(SYM_USERS, id)) {
4387 		yyerror2("user %s is not within scope", id);
4388 		free(id);
4389 		goto bad;
4390 	}
4391 	usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
4392 						   (hashtab_key_t) id);
4393 	if (!usrdatum) {
4394 		yyerror2("user %s is not defined", id);
4395 		free(id);
4396 		goto bad;
4397 	}
4398 	c->user = usrdatum->s.value;
4399 
4400 	/* no need to keep the user name */
4401 	free(id);
4402 
4403 	/* extract the role */
4404 	id = (char *)queue_remove(id_queue);
4405 	if (!id) {
4406 		yyerror("no role name for sid context definition?");
4407 		return -1;
4408 	}
4409 	if (!is_id_in_scope(SYM_ROLES, id)) {
4410 		yyerror2("role %s is not within scope", id);
4411 		free(id);
4412 		return -1;
4413 	}
4414 	role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
4415 					       (hashtab_key_t) id);
4416 	if (!role) {
4417 		yyerror2("role %s is not defined", id);
4418 		free(id);
4419 		return -1;
4420 	}
4421 	c->role = role->s.value;
4422 
4423 	/* no need to keep the role name */
4424 	free(id);
4425 
4426 	/* extract the type */
4427 	id = (char *)queue_remove(id_queue);
4428 	if (!id) {
4429 		yyerror("no type name for sid context definition?");
4430 		return -1;
4431 	}
4432 	if (!is_id_in_scope(SYM_TYPES, id)) {
4433 		yyerror2("type %s is not within scope", id);
4434 		free(id);
4435 		return -1;
4436 	}
4437 	typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
4438 						   (hashtab_key_t) id);
4439 	if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
4440 		yyerror2("type %s is not defined or is an attribute", id);
4441 		free(id);
4442 		return -1;
4443 	}
4444 	c->type = typdatum->s.value;
4445 
4446 	/* no need to keep the type name */
4447 	free(id);
4448 
4449 	if (mlspol) {
4450 		/* extract the low sensitivity */
4451 		id = (char *)queue_head(id_queue);
4452 		if (!id) {
4453 			yyerror("no sensitivity name for sid context"
4454 				" definition?");
4455 			return -1;
4456 		}
4457 
4458 		id = (char *)queue_remove(id_queue);
4459 		for (l = 0; l < 2; l++) {
4460 			levdatum = (level_datum_t *)
4461 			    hashtab_search(policydbp->p_levels.table,
4462 					   (hashtab_key_t) id);
4463 			if (!levdatum) {
4464 				yyerror2("Sensitivity %s is not defined", id);
4465 				free(id);
4466 				return -1;
4467 			}
4468 			free(id);
4469 			c->range.level[l].sens = levdatum->level->sens;
4470 
4471 			/* extract low category set */
4472 			while ((id = queue_remove(id_queue))) {
4473 				if (parse_categories(id, levdatum,
4474 						     &c->range.level[l].cat)) {
4475 					free(id);
4476 					return -1;
4477 				}
4478 				free(id);
4479 			}
4480 
4481 			/* extract high sensitivity */
4482 			id = (char *)queue_remove(id_queue);
4483 			if (!id)
4484 				break;
4485 		}
4486 
4487 		if (l == 0) {
4488 			c->range.level[1].sens = c->range.level[0].sens;
4489 			if (ebitmap_cpy(&c->range.level[1].cat,
4490 					&c->range.level[0].cat)) {
4491 
4492 				yyerror("out of memory");
4493 				goto bad;
4494 			}
4495 		}
4496 	}
4497 
4498 	if (!policydb_context_isvalid(policydbp, c)) {
4499 		yyerror("invalid security context");
4500 		goto bad;
4501 	}
4502 	return 0;
4503 
4504       bad:
4505 	context_destroy(c);
4506 
4507 	return -1;
4508 }
4509 
define_initial_sid_context(void)4510 int define_initial_sid_context(void)
4511 {
4512 	char *id;
4513 	ocontext_t *c, *head;
4514 
4515 	if (pass == 1) {
4516 		id = (char *)queue_remove(id_queue);
4517 		free(id);
4518 		parse_security_context(NULL);
4519 		return 0;
4520 	}
4521 
4522 	id = (char *)queue_remove(id_queue);
4523 	if (!id) {
4524 		yyerror("no sid name for SID context definition?");
4525 		return -1;
4526 	}
4527 	head = policydbp->ocontexts[OCON_ISID];
4528 	for (c = head; c; c = c->next) {
4529 		if (!strcmp(id, c->u.name))
4530 			break;
4531 	}
4532 
4533 	if (!c) {
4534 		yyerror2("SID %s is not defined", id);
4535 		free(id);
4536 		return -1;
4537 	}
4538 	if (c->context[0].user) {
4539 		yyerror2("The context for SID %s is multiply defined", id);
4540 		free(id);
4541 		return -1;
4542 	}
4543 	/* no need to keep the sid name */
4544 	free(id);
4545 
4546 	if (parse_security_context(&c->context[0]))
4547 		return -1;
4548 
4549 	return 0;
4550 }
4551 
define_fs_context(unsigned int major,unsigned int minor)4552 int define_fs_context(unsigned int major, unsigned int minor)
4553 {
4554 	ocontext_t *newc, *c, *head;
4555 
4556 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4557 		yyerror("fscon not supported for target");
4558 		return -1;
4559 	}
4560 
4561 	if (pass == 1) {
4562 		parse_security_context(NULL);
4563 		parse_security_context(NULL);
4564 		return 0;
4565 	}
4566 
4567 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4568 	if (!newc) {
4569 		yyerror("out of memory");
4570 		return -1;
4571 	}
4572 	memset(newc, 0, sizeof(ocontext_t));
4573 
4574 	newc->u.name = (char *)malloc(6);
4575 	if (!newc->u.name) {
4576 		yyerror("out of memory");
4577 		free(newc);
4578 		return -1;
4579 	}
4580 	sprintf(newc->u.name, "%02x:%02x", major, minor);
4581 
4582 	if (parse_security_context(&newc->context[0])) {
4583 		free(newc->u.name);
4584 		free(newc);
4585 		return -1;
4586 	}
4587 	if (parse_security_context(&newc->context[1])) {
4588 		context_destroy(&newc->context[0]);
4589 		free(newc->u.name);
4590 		free(newc);
4591 		return -1;
4592 	}
4593 	head = policydbp->ocontexts[OCON_FS];
4594 
4595 	for (c = head; c; c = c->next) {
4596 		if (!strcmp(newc->u.name, c->u.name)) {
4597 			yyerror2("duplicate entry for file system %s",
4598 				 newc->u.name);
4599 			context_destroy(&newc->context[0]);
4600 			context_destroy(&newc->context[1]);
4601 			free(newc->u.name);
4602 			free(newc);
4603 			return -1;
4604 		}
4605 	}
4606 
4607 	newc->next = head;
4608 	policydbp->ocontexts[OCON_FS] = newc;
4609 
4610 	return 0;
4611 }
4612 
define_pirq_context(unsigned int pirq)4613 int define_pirq_context(unsigned int pirq)
4614 {
4615 	ocontext_t *newc, *c, *l, *head;
4616 	char *id;
4617 
4618 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4619 		yyerror("pirqcon not supported for target");
4620 		return -1;
4621 	}
4622 
4623 	if (pass == 1) {
4624 		id = (char *) queue_remove(id_queue);
4625 		free(id);
4626 		parse_security_context(NULL);
4627 		return 0;
4628 	}
4629 
4630 	newc = malloc(sizeof(ocontext_t));
4631 	if (!newc) {
4632 		yyerror("out of memory");
4633 		return -1;
4634 	}
4635 	memset(newc, 0, sizeof(ocontext_t));
4636 
4637 	newc->u.pirq = pirq;
4638 
4639 	if (parse_security_context(&newc->context[0])) {
4640 		free(newc);
4641 		return -1;
4642 	}
4643 
4644 	head = policydbp->ocontexts[OCON_XEN_PIRQ];
4645 	for (l = NULL, c = head; c; l = c, c = c->next) {
4646 		unsigned int pirq2;
4647 
4648 		pirq2 = c->u.pirq;
4649 		if (pirq == pirq2) {
4650 			yyerror2("duplicate pirqcon entry for %d ", pirq);
4651 			goto bad;
4652 		}
4653 	}
4654 
4655 	if (l)
4656 		l->next = newc;
4657 	else
4658 		policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
4659 
4660 	return 0;
4661 
4662 bad:
4663 	free(newc);
4664 	return -1;
4665 }
4666 
define_iomem_context(uint64_t low,uint64_t high)4667 int define_iomem_context(uint64_t low, uint64_t high)
4668 {
4669 	ocontext_t *newc, *c, *l, *head;
4670 	char *id;
4671 
4672 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4673 		yyerror("iomemcon not supported for target");
4674 		return -1;
4675 	}
4676 
4677 	if (pass == 1) {
4678 		id = (char *)queue_remove(id_queue);
4679 		free(id);
4680 		parse_security_context(NULL);
4681 		return 0;
4682 	}
4683 
4684 	newc = malloc(sizeof(ocontext_t));
4685 	if (!newc) {
4686 		yyerror("out of memory");
4687 		return -1;
4688 	}
4689 	memset(newc, 0, sizeof(ocontext_t));
4690 
4691 	newc->u.iomem.low_iomem  = low;
4692 	newc->u.iomem.high_iomem = high;
4693 
4694 	if (low > high) {
4695 		yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high);
4696 		free(newc);
4697 		return -1;
4698 	}
4699 
4700 	if (parse_security_context(&newc->context[0])) {
4701 		free(newc);
4702 		return -1;
4703 	}
4704 
4705 	head = policydbp->ocontexts[OCON_XEN_IOMEM];
4706 	for (l = NULL, c = head; c; l = c, c = c->next) {
4707 		uint64_t low2, high2;
4708 
4709 		low2 = c->u.iomem.low_iomem;
4710 		high2 = c->u.iomem.high_iomem;
4711 		if (low <= high2 && low2 <= high) {
4712 			yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with "
4713 				"earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high,
4714 				low2, high2);
4715 			goto bad;
4716 		}
4717 	}
4718 
4719 	if (l)
4720 		l->next = newc;
4721 	else
4722 		policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
4723 
4724 	return 0;
4725 
4726 bad:
4727 	free(newc);
4728 	return -1;
4729 }
4730 
define_ioport_context(unsigned long low,unsigned long high)4731 int define_ioport_context(unsigned long low, unsigned long high)
4732 {
4733 	ocontext_t *newc, *c, *l, *head;
4734 	char *id;
4735 
4736 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4737 		yyerror("ioportcon not supported for target");
4738 		return -1;
4739 	}
4740 
4741 	if (pass == 1) {
4742 		id = (char *)queue_remove(id_queue);
4743 		free(id);
4744 		parse_security_context(NULL);
4745 		return 0;
4746 	}
4747 
4748 	newc = malloc(sizeof(ocontext_t));
4749 	if (!newc) {
4750 		yyerror("out of memory");
4751 		return -1;
4752 	}
4753 	memset(newc, 0, sizeof(ocontext_t));
4754 
4755 	newc->u.ioport.low_ioport  = low;
4756 	newc->u.ioport.high_ioport = high;
4757 
4758 	if (low > high) {
4759 		yyerror2("low ioport 0x%lx exceeds high ioport 0x%lx", low, high);
4760 		free(newc);
4761 		return -1;
4762 	}
4763 
4764 	if (parse_security_context(&newc->context[0])) {
4765 		free(newc);
4766 		return -1;
4767 	}
4768 
4769 	head = policydbp->ocontexts[OCON_XEN_IOPORT];
4770 	for (l = NULL, c = head; c; l = c, c = c->next) {
4771 		uint32_t low2, high2;
4772 
4773 		low2 = c->u.ioport.low_ioport;
4774 		high2 = c->u.ioport.high_ioport;
4775 		if (low <= high2 && low2 <= high) {
4776 			yyerror2("ioportcon entry for 0x%lx-0x%lx overlaps with"
4777 				"earlier entry 0x%x-0x%x", low, high,
4778 				low2, high2);
4779 			goto bad;
4780 		}
4781 	}
4782 
4783 	if (l)
4784 		l->next = newc;
4785 	else
4786 		policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
4787 
4788 	return 0;
4789 
4790 bad:
4791 	free(newc);
4792 	return -1;
4793 }
4794 
define_pcidevice_context(unsigned long device)4795 int define_pcidevice_context(unsigned long device)
4796 {
4797 	ocontext_t *newc, *c, *l, *head;
4798 	char *id;
4799 
4800 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4801 		yyerror("pcidevicecon not supported for target");
4802 		return -1;
4803 	}
4804 
4805 	if (pass == 1) {
4806 		id = (char *) queue_remove(id_queue);
4807 		free(id);
4808 		parse_security_context(NULL);
4809 		return 0;
4810 	}
4811 
4812 	newc = malloc(sizeof(ocontext_t));
4813 	if (!newc) {
4814 		yyerror("out of memory");
4815 		return -1;
4816 	}
4817 	memset(newc, 0, sizeof(ocontext_t));
4818 
4819 	newc->u.device = device;
4820 
4821 	if (parse_security_context(&newc->context[0])) {
4822 		free(newc);
4823 		return -1;
4824 	}
4825 
4826 	head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
4827 	for (l = NULL, c = head; c; l = c, c = c->next) {
4828 		unsigned int device2;
4829 
4830 		device2 = c->u.device;
4831 		if (device == device2) {
4832 			yyerror2("duplicate pcidevicecon entry for 0x%lx",
4833 				 device);
4834 			goto bad;
4835 		}
4836 	}
4837 
4838 	if (l)
4839 		l->next = newc;
4840 	else
4841 		policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
4842 
4843 	return 0;
4844 
4845 bad:
4846 	free(newc);
4847 	return -1;
4848 }
4849 
define_devicetree_context(void)4850 int define_devicetree_context(void)
4851 {
4852 	ocontext_t *newc, *c, *l, *head;
4853 
4854 	if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4855 		yyerror("devicetreecon not supported for target");
4856 		return -1;
4857 	}
4858 
4859 	if (pass == 1) {
4860 		free(queue_remove(id_queue));
4861 		parse_security_context(NULL);
4862 		return 0;
4863 	}
4864 
4865 	newc = malloc(sizeof(ocontext_t));
4866 	if (!newc) {
4867 		yyerror("out of memory");
4868 		return -1;
4869 	}
4870 	memset(newc, 0, sizeof(ocontext_t));
4871 
4872 	newc->u.name = (char *)queue_remove(id_queue);
4873 	if (!newc->u.name) {
4874 		free(newc);
4875 		return -1;
4876 	}
4877 
4878 	if (parse_security_context(&newc->context[0])) {
4879 		free(newc->u.name);
4880 		free(newc);
4881 		return -1;
4882 	}
4883 
4884 	head = policydbp->ocontexts[OCON_XEN_DEVICETREE];
4885 	for (l = NULL, c = head; c; l = c, c = c->next) {
4886 		if (strcmp(newc->u.name, c->u.name) == 0) {
4887 			yyerror2("duplicate devicetree entry for '%s'", newc->u.name);
4888 			goto bad;
4889 		}
4890 	}
4891 
4892 	if (l)
4893 		l->next = newc;
4894 	else
4895 		policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc;
4896 
4897 	return 0;
4898 
4899 bad:
4900 	free(newc->u.name);
4901 	free(newc);
4902 	return -1;
4903 }
4904 
define_port_context(unsigned int low,unsigned int high)4905 int define_port_context(unsigned int low, unsigned int high)
4906 {
4907 	ocontext_t *newc, *c, *l, *head;
4908 	unsigned int protocol;
4909 	char *id;
4910 
4911 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4912 		yyerror("portcon not supported for target");
4913 		return -1;
4914 	}
4915 
4916 	if (pass == 1) {
4917 		id = (char *)queue_remove(id_queue);
4918 		free(id);
4919 		parse_security_context(NULL);
4920 		return 0;
4921 	}
4922 
4923 	newc = malloc(sizeof(ocontext_t));
4924 	if (!newc) {
4925 		yyerror("out of memory");
4926 		return -1;
4927 	}
4928 	memset(newc, 0, sizeof(ocontext_t));
4929 
4930 	id = (char *)queue_remove(id_queue);
4931 	if (!id) {
4932 		free(newc);
4933 		return -1;
4934 	}
4935 	if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4936 		protocol = IPPROTO_TCP;
4937 	} else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4938 		protocol = IPPROTO_UDP;
4939 	} else if ((strcmp(id, "dccp") == 0) || (strcmp(id, "DCCP") == 0)) {
4940 		protocol = IPPROTO_DCCP;
4941 	} else if ((strcmp(id, "sctp") == 0) || (strcmp(id, "SCTP") == 0)) {
4942 		protocol = IPPROTO_SCTP;
4943 	} else {
4944 		yyerror2("unrecognized protocol %s", id);
4945 		goto bad;
4946 	}
4947 
4948 	newc->u.port.protocol = protocol;
4949 	newc->u.port.low_port = low;
4950 	newc->u.port.high_port = high;
4951 
4952 	if (low > high) {
4953 		yyerror2("low port %d exceeds high port %d", low, high);
4954 		goto bad;
4955 	}
4956 
4957 	if (parse_security_context(&newc->context[0])) {
4958 		goto bad;
4959 	}
4960 
4961 	/* Preserve the matching order specified in the configuration. */
4962 	head = policydbp->ocontexts[OCON_PORT];
4963 	for (l = NULL, c = head; c; l = c, c = c->next) {
4964 		unsigned int prot2, low2, high2;
4965 
4966 		prot2 = c->u.port.protocol;
4967 		low2 = c->u.port.low_port;
4968 		high2 = c->u.port.high_port;
4969 		if (protocol != prot2)
4970 			continue;
4971 		if (low == low2 && high == high2) {
4972 			yyerror2("duplicate portcon entry for %s %d-%d ", id,
4973 				 low, high);
4974 			goto bad;
4975 		}
4976 		if (low2 <= low && high2 >= high) {
4977 			yyerror2("portcon entry for %s %d-%d hidden by earlier "
4978 				 "entry for %d-%d", id, low, high, low2, high2);
4979 			goto bad;
4980 		}
4981 	}
4982 
4983 	if (l)
4984 		l->next = newc;
4985 	else
4986 		policydbp->ocontexts[OCON_PORT] = newc;
4987 
4988 	free(id);
4989 	return 0;
4990 
4991       bad:
4992 	free(id);
4993 	free(newc);
4994 	return -1;
4995 }
4996 
define_ibpkey_context(unsigned int low,unsigned int high)4997 int define_ibpkey_context(unsigned int low, unsigned int high)
4998 {
4999 	ocontext_t *newc, *c, *l, *head;
5000 	struct in6_addr subnet_prefix;
5001 	char *id;
5002 	int rc = 0;
5003 
5004 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5005 		yyerror("ibpkeycon not supported for target");
5006 		return -1;
5007 	}
5008 
5009 	if (pass == 1) {
5010 		id = (char *)queue_remove(id_queue);
5011 		free(id);
5012 		parse_security_context(NULL);
5013 		return 0;
5014 	}
5015 
5016 	newc = malloc(sizeof(*newc));
5017 	if (!newc) {
5018 		yyerror("out of memory");
5019 		return -1;
5020 	}
5021 	memset(newc, 0, sizeof(*newc));
5022 
5023 	id = queue_remove(id_queue);
5024 	if (!id) {
5025 		yyerror("failed to read the subnet prefix");
5026 		rc = -1;
5027 		goto out;
5028 	}
5029 
5030 	rc = inet_pton(AF_INET6, id, &subnet_prefix);
5031 	free(id);
5032 	if (rc < 1) {
5033 		yyerror("failed to parse the subnet prefix");
5034 		if (rc == 0)
5035 			rc = -1;
5036 		goto out;
5037 	}
5038 
5039 	if (subnet_prefix.s6_addr[2] || subnet_prefix.s6_addr[3]) {
5040 		yyerror("subnet prefix should be 0's in the low order 64 bits.");
5041 		rc = -1;
5042 		goto out;
5043 	}
5044 
5045 	if (low > 0xffff || high > 0xffff) {
5046 		yyerror("pkey value too large, pkeys are 16 bits.");
5047 		rc = -1;
5048 		goto out;
5049 	}
5050 
5051 	memcpy(&newc->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0],
5052 	       sizeof(newc->u.ibpkey.subnet_prefix));
5053 
5054 	newc->u.ibpkey.low_pkey = low;
5055 	newc->u.ibpkey.high_pkey = high;
5056 
5057 	if (low > high) {
5058 		yyerror2("low pkey %d exceeds high pkey %d", low, high);
5059 		rc = -1;
5060 		goto out;
5061 	}
5062 
5063 	rc = parse_security_context(&newc->context[0]);
5064 	if (rc)
5065 		goto out;
5066 
5067 	/* Preserve the matching order specified in the configuration. */
5068 	head = policydbp->ocontexts[OCON_IBPKEY];
5069 	for (l = NULL, c = head; c; l = c, c = c->next) {
5070 		unsigned int low2, high2;
5071 
5072 		low2 = c->u.ibpkey.low_pkey;
5073 		high2 = c->u.ibpkey.high_pkey;
5074 
5075 		if (low == low2 && high == high2 &&
5076 		    c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5077 			yyerror2("duplicate ibpkeycon entry for %d-%d ",
5078 				 low, high);
5079 			rc = -1;
5080 			goto out;
5081 		}
5082 		if (low2 <= low && high2 >= high &&
5083 		    c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5084 			yyerror2("ibpkeycon entry for %d-%d hidden by earlier entry for %d-%d",
5085 				 low, high, low2, high2);
5086 			rc = -1;
5087 			goto out;
5088 		}
5089 	}
5090 
5091 	if (l)
5092 		l->next = newc;
5093 	else
5094 		policydbp->ocontexts[OCON_IBPKEY] = newc;
5095 
5096 	return 0;
5097 
5098 out:
5099 	free(newc);
5100 	return rc;
5101 }
5102 
define_ibendport_context(unsigned int port)5103 int define_ibendport_context(unsigned int port)
5104 {
5105 	ocontext_t *newc, *c, *l, *head;
5106 	char *id;
5107 	int rc = 0;
5108 
5109 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5110 		yyerror("ibendportcon not supported for target");
5111 		return -1;
5112 	}
5113 
5114 	if (pass == 1) {
5115 		id = (char *)queue_remove(id_queue);
5116 		free(id);
5117 		parse_security_context(NULL);
5118 		return 0;
5119 	}
5120 
5121 	if (port > 0xff || port == 0) {
5122 		yyerror2("Invalid ibendport port number %d, should be 0 < port < 256", port);
5123 		return -1;
5124 	}
5125 
5126 	newc = malloc(sizeof(*newc));
5127 	if (!newc) {
5128 		yyerror("out of memory");
5129 		return -1;
5130 	}
5131 	memset(newc, 0, sizeof(*newc));
5132 
5133 	newc->u.ibendport.dev_name = queue_remove(id_queue);
5134 	if (!newc->u.ibendport.dev_name) {
5135 		yyerror("failed to read infiniband device name.");
5136 		rc = -1;
5137 		goto out;
5138 	}
5139 
5140 	if (strlen(newc->u.ibendport.dev_name) > IB_DEVICE_NAME_MAX - 1) {
5141 		yyerror2("infiniband device name %s exceeds max length of 63.", newc->u.ibendport.dev_name);
5142 		rc = -1;
5143 		goto out;
5144 	}
5145 
5146 	newc->u.ibendport.port = port;
5147 
5148 	if (parse_security_context(&newc->context[0])) {
5149 		free(newc);
5150 		return -1;
5151 	}
5152 
5153 	/* Preserve the matching order specified in the configuration. */
5154 	head = policydbp->ocontexts[OCON_IBENDPORT];
5155 	for (l = NULL, c = head; c; l = c, c = c->next) {
5156 		unsigned int port2;
5157 
5158 		port2 = c->u.ibendport.port;
5159 
5160 		if (port == port2 &&
5161 		    !strcmp(c->u.ibendport.dev_name,
5162 			     newc->u.ibendport.dev_name)) {
5163 			yyerror2("duplicate ibendportcon entry for %s port %u",
5164 				 newc->u.ibendport.dev_name, port);
5165 			rc = -1;
5166 			goto out;
5167 		}
5168 	}
5169 
5170 	if (l)
5171 		l->next = newc;
5172 	else
5173 		policydbp->ocontexts[OCON_IBENDPORT] = newc;
5174 
5175 	return 0;
5176 
5177 out:
5178 	free(newc->u.ibendport.dev_name);
5179 	free(newc);
5180 	return rc;
5181 }
5182 
define_netif_context(void)5183 int define_netif_context(void)
5184 {
5185 	ocontext_t *newc, *c, *head;
5186 
5187 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5188 		yyerror("netifcon not supported for target");
5189 		return -1;
5190 	}
5191 
5192 	if (pass == 1) {
5193 		free(queue_remove(id_queue));
5194 		parse_security_context(NULL);
5195 		parse_security_context(NULL);
5196 		return 0;
5197 	}
5198 
5199 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5200 	if (!newc) {
5201 		yyerror("out of memory");
5202 		return -1;
5203 	}
5204 	memset(newc, 0, sizeof(ocontext_t));
5205 
5206 	newc->u.name = (char *)queue_remove(id_queue);
5207 	if (!newc->u.name) {
5208 		free(newc);
5209 		return -1;
5210 	}
5211 	if (parse_security_context(&newc->context[0])) {
5212 		free(newc->u.name);
5213 		free(newc);
5214 		return -1;
5215 	}
5216 	if (parse_security_context(&newc->context[1])) {
5217 		context_destroy(&newc->context[0]);
5218 		free(newc->u.name);
5219 		free(newc);
5220 		return -1;
5221 	}
5222 	head = policydbp->ocontexts[OCON_NETIF];
5223 
5224 	for (c = head; c; c = c->next) {
5225 		if (!strcmp(newc->u.name, c->u.name)) {
5226 			yyerror2("duplicate entry for network interface %s",
5227 				 newc->u.name);
5228 			context_destroy(&newc->context[0]);
5229 			context_destroy(&newc->context[1]);
5230 			free(newc->u.name);
5231 			free(newc);
5232 			return -1;
5233 		}
5234 	}
5235 
5236 	newc->next = head;
5237 	policydbp->ocontexts[OCON_NETIF] = newc;
5238 	return 0;
5239 }
5240 
insert_ipv4_node(ocontext_t * newc)5241 static int insert_ipv4_node(ocontext_t *newc)
5242 {
5243 	ocontext_t *c, *l;
5244 	char addr[INET_ADDRSTRLEN];
5245 	char mask[INET_ADDRSTRLEN];
5246 
5247 	/* Create order of most specific to least retaining
5248 	   the order specified in the configuration. */
5249 	for (l = NULL, c = policydbp->ocontexts[OCON_NODE]; c; l = c, c = c->next) {
5250 		if (newc->u.node.mask == c->u.node.mask &&
5251 		    newc->u.node.addr == c->u.node.addr) {
5252 			yyerror2("duplicate entry for network node %s %s",
5253 				 inet_ntop(AF_INET, &newc->u.node.addr, addr, INET_ADDRSTRLEN) ?: "<invalid>",
5254 				 inet_ntop(AF_INET, &newc->u.node.mask, mask, INET_ADDRSTRLEN) ?: "<invalid>");
5255 			context_destroy(&newc->context[0]);
5256 			free(newc);
5257 			return -1;
5258 		}
5259 
5260 		if (newc->u.node.mask > c->u.node.mask)
5261 			break;
5262 	}
5263 
5264 	newc->next = c;
5265 
5266 	if (l)
5267 		l->next = newc;
5268 	else
5269 		policydbp->ocontexts[OCON_NODE] = newc;
5270 
5271 	return 0;
5272 }
5273 
define_ipv4_node_context(void)5274 int define_ipv4_node_context(void)
5275 {
5276 	char *id;
5277 	int rc = 0;
5278 	struct in_addr addr, mask;
5279 	ocontext_t *newc;
5280 
5281 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5282 		yyerror("nodecon not supported for target");
5283 		return -1;
5284 	}
5285 
5286 	if (pass == 1) {
5287 		free(queue_remove(id_queue));
5288 		free(queue_remove(id_queue));
5289 		parse_security_context(NULL);
5290 		return 0;
5291 	}
5292 
5293 	id = queue_remove(id_queue);
5294 	if (!id) {
5295 		yyerror("failed to read ipv4 address");
5296 		return -1;
5297 	}
5298 
5299 	rc = inet_pton(AF_INET, id, &addr);
5300 	if (rc < 1) {
5301 		yyerror2("failed to parse ipv4 address %s", id);
5302 		free(id);
5303 		return -1;
5304 	}
5305 	free(id);
5306 
5307 	id = queue_remove(id_queue);
5308 	if (!id) {
5309 		yyerror("failed to read ipv4 address");
5310 		return -1;
5311 	}
5312 
5313 	rc = inet_pton(AF_INET, id, &mask);
5314 	if (rc < 1) {
5315 		yyerror2("failed to parse ipv4 mask %s", id);
5316 		free(id);
5317 		return -1;
5318 	}
5319 
5320 	free(id);
5321 
5322 	if (mask.s_addr != 0 && ((~be32toh(mask.s_addr) + 1) & ~be32toh(mask.s_addr)) != 0) {
5323 		yywarn("ipv4 mask is not contiguous");
5324 	}
5325 
5326 	if ((~mask.s_addr & addr.s_addr) != 0) {
5327 		yywarn("host bits in ipv4 address set");
5328 	}
5329 
5330 	newc = malloc(sizeof(ocontext_t));
5331 	if (!newc) {
5332 		yyerror("out of memory");
5333 		return -1;
5334 	}
5335 
5336 	memset(newc, 0, sizeof(ocontext_t));
5337 	newc->u.node.addr = addr.s_addr;
5338 	newc->u.node.mask = mask.s_addr;
5339 
5340 	if (parse_security_context(&newc->context[0])) {
5341 		free(newc);
5342 		return -1;
5343 	}
5344 
5345 	return insert_ipv4_node(newc);
5346 }
5347 
define_ipv4_cidr_node_context(void)5348 int define_ipv4_cidr_node_context(void)
5349 {
5350 	char *endptr, *id, *split;
5351 	unsigned long mask_bits;
5352 	uint32_t mask;
5353 	struct in_addr addr;
5354 	ocontext_t *newc;
5355 	int rc;
5356 
5357 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5358 		yyerror("nodecon not supported for target");
5359 		return -1;
5360 	}
5361 
5362 	if (pass == 1) {
5363 		free(queue_remove(id_queue));
5364 		parse_security_context(NULL);
5365 		return 0;
5366 	}
5367 
5368 	id = queue_remove(id_queue);
5369 	if (!id) {
5370 		yyerror("failed to read IPv4 address");
5371 		return -1;
5372 	}
5373 
5374 	split = strchr(id, '/');
5375 	if (!split) {
5376 		yyerror2("invalid IPv4 CIDR notation: %s", id);
5377 		free(id);
5378 		return -1;
5379 	}
5380 	*split = '\0';
5381 
5382 	rc = inet_pton(AF_INET, id, &addr);
5383 	if (rc < 1) {
5384 		yyerror2("failed to parse IPv4 address %s", id);
5385 		free(id);
5386 		return -1;
5387 	}
5388 
5389 	errno = 0;
5390 	mask_bits = strtoul(split + 1, &endptr, 10);
5391 	if (errno || *endptr != '\0' || mask_bits > 32) {
5392 		yyerror2("invalid mask in IPv4 CIDR notation: %s", split + 1);
5393 		free(id);
5394 		return -1;
5395 	}
5396 
5397 	free(id);
5398 
5399 	if (mask_bits == 0) {
5400 		yywarn("IPv4 CIDR mask of 0, matching all IPs");
5401 		mask = 0;
5402 	} else {
5403 		mask = ~((UINT32_C(1) << (32 - mask_bits)) - 1);
5404 		mask = htobe32(mask);
5405 	}
5406 
5407 	if ((~mask & addr.s_addr) != 0)
5408 		yywarn("host bits in IPv4 address set");
5409 
5410 	newc = calloc(1, sizeof(ocontext_t));
5411 	if (!newc) {
5412 		yyerror("out of memory");
5413 		return -1;
5414 	}
5415 
5416 	newc->u.node.addr = addr.s_addr & mask;
5417 	newc->u.node.mask = mask;
5418 
5419 	if (parse_security_context(&newc->context[0])) {
5420 		free(newc);
5421 		return -1;
5422 	}
5423 
5424 	return insert_ipv4_node(newc);
5425 }
5426 
ipv6_is_mask_contiguous(const struct in6_addr * mask)5427 static int ipv6_is_mask_contiguous(const struct in6_addr *mask)
5428 {
5429 	int filled = 1;
5430 	unsigned i;
5431 
5432 	for (i = 0; i < 16; i++) {
5433 		if ((((~mask->s6_addr[i] & 0xFF) + 1) & (~mask->s6_addr[i] & 0xFF)) != 0) {
5434 			return 0;
5435 		}
5436 		if (!filled && mask->s6_addr[i] != 0) {
5437 			return 0;
5438 		}
5439 
5440 		if (filled && mask->s6_addr[i] != 0xFF) {
5441 			filled = 0;
5442 		}
5443 	}
5444 
5445 	return 1;
5446 }
5447 
ipv6_has_host_bits_set(const struct in6_addr * addr,const struct in6_addr * mask)5448 static int ipv6_has_host_bits_set(const struct in6_addr *addr, const struct in6_addr *mask)
5449 {
5450 	unsigned i;
5451 
5452 	for (i = 0; i < 16; i++) {
5453 		if ((addr->s6_addr[i] & ~mask->s6_addr[i]) != 0) {
5454 			return 1;
5455 		}
5456 	}
5457 
5458 	return 0;
5459 }
5460 
ipv6_cidr_bits_to_mask(unsigned long cidr_bits,struct in6_addr * mask)5461 static void ipv6_cidr_bits_to_mask(unsigned long cidr_bits, struct in6_addr *mask)
5462 {
5463 	unsigned i;
5464 
5465 	for (i = 0; i < 4; i++) {
5466 		if (cidr_bits == 0) {
5467 			mask->s6_addr32[i] = 0;
5468 		} else if (cidr_bits >= 32) {
5469 			mask->s6_addr32[i] = ~UINT32_C(0);
5470 		} else {
5471 			mask->s6_addr32[i] = htobe32(~((UINT32_C(1) << (32 - cidr_bits)) - 1));
5472 		}
5473 
5474 		if (cidr_bits >= 32)
5475 			cidr_bits -= 32;
5476 		else
5477 			cidr_bits = 0;
5478 	}
5479 }
5480 
insert_ipv6_node(ocontext_t * newc)5481 static int insert_ipv6_node(ocontext_t *newc)
5482 {
5483 	ocontext_t *c, *l;
5484 	char addr[INET6_ADDRSTRLEN];
5485 	char mask[INET6_ADDRSTRLEN];
5486 
5487 	/* Create order of most specific to least retaining
5488 	   the order specified in the configuration. */
5489 	for (l = NULL, c = policydbp->ocontexts[OCON_NODE6]; c; l = c, c = c->next) {
5490 		if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) == 0 &&
5491 		    memcmp(&newc->u.node6.addr, &c->u.node6.addr, 16) == 0) {
5492 			yyerror2("duplicate entry for network node %s %s",
5493 				 inet_ntop(AF_INET6, &newc->u.node6.addr, addr, INET6_ADDRSTRLEN) ?: "<invalid>",
5494 				 inet_ntop(AF_INET6, &newc->u.node6.mask, mask, INET6_ADDRSTRLEN) ?: "<invalid>");
5495 			context_destroy(&newc->context[0]);
5496 			free(newc);
5497 			return -1;
5498 		}
5499 
5500 		if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
5501 			break;
5502 	}
5503 
5504 	newc->next = c;
5505 
5506 	if (l)
5507 		l->next = newc;
5508 	else
5509 		policydbp->ocontexts[OCON_NODE6] = newc;
5510 
5511 	return 0;
5512 }
5513 
define_ipv6_node_context(void)5514 int define_ipv6_node_context(void)
5515 {
5516 	char *id;
5517 	int rc = 0;
5518 	struct in6_addr addr, mask;
5519 	ocontext_t *newc;
5520 
5521 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5522 		yyerror("nodecon not supported for target");
5523 		return -1;
5524 	}
5525 
5526 	if (pass == 1) {
5527 		free(queue_remove(id_queue));
5528 		free(queue_remove(id_queue));
5529 		parse_security_context(NULL);
5530 		return 0;
5531 	}
5532 
5533 	id = queue_remove(id_queue);
5534 	if (!id) {
5535 		yyerror("failed to read ipv6 address");
5536 		return -1;
5537 	}
5538 
5539 	rc = inet_pton(AF_INET6, id, &addr);
5540 	if (rc < 1) {
5541 		yyerror2("failed to parse ipv6 address %s", id);
5542 		free(id);
5543 		return -1;
5544 	}
5545 
5546 	free(id);
5547 
5548 	id = queue_remove(id_queue);
5549 	if (!id) {
5550 		yyerror("failed to read ipv6 address");
5551 		return -1;
5552 	}
5553 
5554 	rc = inet_pton(AF_INET6, id, &mask);
5555 	if (rc < 1) {
5556 		yyerror2("failed to parse ipv6 mask %s", id);
5557 		free(id);
5558 		return -1;
5559 	}
5560 
5561 	free(id);
5562 
5563 	if (!ipv6_is_mask_contiguous(&mask)) {
5564 		yywarn("ipv6 mask is not contiguous");
5565 	}
5566 
5567 	if (ipv6_has_host_bits_set(&addr, &mask)) {
5568 		yywarn("host bits in ipv6 address set");
5569 	}
5570 
5571 	newc = malloc(sizeof(ocontext_t));
5572 	if (!newc) {
5573 		yyerror("out of memory");
5574 		return -1;
5575 	}
5576 
5577 	memset(newc, 0, sizeof(ocontext_t));
5578 	memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
5579 	memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
5580 
5581 	if (parse_security_context(&newc->context[0])) {
5582 		free(newc);
5583 		return -1;
5584 	}
5585 
5586 	return insert_ipv6_node(newc);
5587 }
5588 
define_ipv6_cidr_node_context(void)5589 int define_ipv6_cidr_node_context(void)
5590 {
5591 	char *endptr, *id, *split;
5592 	unsigned long mask_bits;
5593 	int rc;
5594 	struct in6_addr addr, mask;
5595 	ocontext_t *newc;
5596 
5597 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5598 		yyerror("nodecon not supported for target");
5599 		return -1;
5600 	}
5601 
5602 	if (pass == 1) {
5603 		free(queue_remove(id_queue));
5604 		free(queue_remove(id_queue));
5605 		parse_security_context(NULL);
5606 		return 0;
5607 	}
5608 
5609 	id = queue_remove(id_queue);
5610 	if (!id) {
5611 		yyerror("failed to read IPv6 address");
5612 		return -1;
5613 	}
5614 
5615 	split = strchr(id, '/');
5616 	if (!split) {
5617 		yyerror2("invalid IPv6 CIDR notation: %s", id);
5618 		free(id);
5619 		return -1;
5620 	}
5621 	*split = '\0';
5622 
5623 	rc = inet_pton(AF_INET6, id, &addr);
5624 	if (rc < 1) {
5625 		yyerror2("failed to parse IPv6 address %s", id);
5626 		free(id);
5627 		return -1;
5628 	}
5629 
5630 	errno = 0;
5631 	mask_bits = strtoul(split + 1, &endptr, 10);
5632 	if (errno || *endptr != '\0' || mask_bits > 128) {
5633 		yyerror2("invalid mask in IPv6 CIDR notation: %s", split + 1);
5634 		free(id);
5635 		return -1;
5636 	}
5637 
5638 	if (mask_bits == 0) {
5639 		yywarn("IPv6 CIDR mask of 0, matching all IPs");
5640 	}
5641 
5642 	ipv6_cidr_bits_to_mask(mask_bits, &mask);
5643 
5644 	if (ipv6_has_host_bits_set(&addr, &mask)) {
5645 		yywarn("host bits in ipv6 address set");
5646 	}
5647 
5648 	free(id);
5649 
5650 	newc = calloc(1, sizeof(ocontext_t));
5651 	if (!newc) {
5652 		yyerror("out of memory");
5653 		return -1;
5654 	}
5655 
5656 	memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
5657 	memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
5658 
5659 	if (parse_security_context(&newc->context[0])) {
5660 		free(newc);
5661 		return -1;
5662 	}
5663 
5664 	return insert_ipv6_node(newc);
5665 }
5666 
define_fs_use(int behavior)5667 int define_fs_use(int behavior)
5668 {
5669 	ocontext_t *newc, *c, *head;
5670 
5671 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5672 		yyerror("fsuse not supported for target");
5673 		return -1;
5674 	}
5675 
5676 	if (pass == 1) {
5677 		free(queue_remove(id_queue));
5678 		parse_security_context(NULL);
5679 		return 0;
5680 	}
5681 
5682 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5683 	if (!newc) {
5684 		yyerror("out of memory");
5685 		return -1;
5686 	}
5687 	memset(newc, 0, sizeof(ocontext_t));
5688 
5689 	newc->u.name = (char *)queue_remove(id_queue);
5690 	if (!newc->u.name) {
5691 		free(newc);
5692 		return -1;
5693 	}
5694 	newc->v.behavior = behavior;
5695 	if (parse_security_context(&newc->context[0])) {
5696 		free(newc->u.name);
5697 		free(newc);
5698 		return -1;
5699 	}
5700 
5701 	head = policydbp->ocontexts[OCON_FSUSE];
5702 
5703 	for (c = head; c; c = c->next) {
5704 		if (!strcmp(newc->u.name, c->u.name)) {
5705 			yyerror2("duplicate fs_use entry for filesystem type %s",
5706 				 newc->u.name);
5707 			context_destroy(&newc->context[0]);
5708 			free(newc->u.name);
5709 			free(newc);
5710 			return -1;
5711 		}
5712 	}
5713 
5714 	newc->next = head;
5715 	policydbp->ocontexts[OCON_FSUSE] = newc;
5716 	return 0;
5717 }
5718 
define_genfs_context_helper(char * fstype,int has_type)5719 static int define_genfs_context_helper(char *fstype, int has_type)
5720 {
5721 	struct genfs *genfs_p, *genfs, *newgenfs;
5722 	ocontext_t *newc, *c, *head, *p;
5723 	class_datum_t *cladatum;
5724 	char *type = NULL;
5725 	const char *sclass;
5726 	size_t len, len2;
5727 
5728 	if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5729 		yyerror("genfs not supported for target");
5730 		return -1;
5731 	}
5732 
5733 	if (pass == 1) {
5734 		free(fstype);
5735 		free(queue_remove(id_queue));
5736 		if (has_type)
5737 			free(queue_remove(id_queue));
5738 		parse_security_context(NULL);
5739 		return 0;
5740 	}
5741 
5742 	for (genfs_p = NULL, genfs = policydbp->genfs;
5743 	     genfs; genfs_p = genfs, genfs = genfs->next) {
5744 		if (strcmp(fstype, genfs->fstype) <= 0)
5745 			break;
5746 	}
5747 
5748 	if (!genfs || strcmp(fstype, genfs->fstype)) {
5749 		newgenfs = malloc(sizeof(struct genfs));
5750 		if (!newgenfs) {
5751 			yyerror("out of memory");
5752 			return -1;
5753 		}
5754 		memset(newgenfs, 0, sizeof(struct genfs));
5755 		newgenfs->fstype = fstype;
5756 		newgenfs->next = genfs;
5757 		if (genfs_p)
5758 			genfs_p->next = newgenfs;
5759 		else
5760 			policydbp->genfs = newgenfs;
5761 		genfs = newgenfs;
5762 	} else {
5763 		free(fstype);
5764 		fstype = NULL;
5765 	}
5766 
5767 	newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5768 	if (!newc) {
5769 		yyerror("out of memory");
5770 		return -1;
5771 	}
5772 	memset(newc, 0, sizeof(ocontext_t));
5773 
5774 	newc->u.name = (char *)queue_remove(id_queue);
5775 	if (!newc->u.name)
5776 		goto fail;
5777 	if (has_type) {
5778 		type = (char *)queue_remove(id_queue);
5779 		if (!type)
5780 			goto fail;
5781 		if (type[1] != 0) {
5782 			yyerror2("invalid type %s", type);
5783 			goto fail;
5784 		}
5785 		switch (type[0]) {
5786 		case 'b':
5787 			sclass = "blk_file";
5788 			break;
5789 		case 'c':
5790 			sclass = "chr_file";
5791 			break;
5792 		case 'd':
5793 			sclass = "dir";
5794 			break;
5795 		case 'p':
5796 			sclass = "fifo_file";
5797 			break;
5798 		case 'l':
5799 			sclass = "lnk_file";
5800 			break;
5801 		case 's':
5802 			sclass = "sock_file";
5803 			break;
5804 		case '-':
5805 			sclass = "file";
5806 			break;
5807 		default:
5808 			yyerror2("invalid type %s", type);
5809 			goto fail;
5810 		}
5811 
5812 		cladatum = hashtab_search(policydbp->p_classes.table,
5813 					  sclass);
5814 		if (!cladatum) {
5815 			yyerror2("could not find class %s for "
5816 				 "genfscon statement", sclass);
5817 			goto fail;
5818 		}
5819 		newc->v.sclass = cladatum->s.value;
5820 	}
5821 	if (parse_security_context(&newc->context[0]))
5822 		goto fail;
5823 
5824 	head = genfs->head;
5825 
5826 	for (p = NULL, c = head; c; p = c, c = c->next) {
5827 		if (!strcmp(newc->u.name, c->u.name) &&
5828 		    (!newc->v.sclass || !c->v.sclass
5829 		     || newc->v.sclass == c->v.sclass)) {
5830 			yyerror2("duplicate entry for genfs entry (%s, %s)",
5831 				 genfs->fstype, newc->u.name);
5832 			goto fail;
5833 		}
5834 		len = strlen(newc->u.name);
5835 		len2 = strlen(c->u.name);
5836 		if (len > len2)
5837 			break;
5838 	}
5839 
5840 	newc->next = c;
5841 	if (p)
5842 		p->next = newc;
5843 	else
5844 		genfs->head = newc;
5845 	free(type);
5846 	return 0;
5847       fail:
5848 	if (type)
5849 		free(type);
5850 	context_destroy(&newc->context[0]);
5851 	if (fstype)
5852 		free(fstype);
5853 	if (newc->u.name)
5854 		free(newc->u.name);
5855 	free(newc);
5856 	return -1;
5857 }
5858 
define_genfs_context(int has_type)5859 int define_genfs_context(int has_type)
5860 {
5861 	return define_genfs_context_helper(queue_remove(id_queue), has_type);
5862 }
5863 
define_range_trans(int class_specified)5864 int define_range_trans(int class_specified)
5865 {
5866 	char *id;
5867 	level_datum_t *levdatum = 0;
5868 	class_datum_t *cladatum;
5869 	range_trans_rule_t *rule;
5870 	int l, add = 1;
5871 
5872 	if (!mlspol) {
5873 		yyerror("range_transition rule in non-MLS configuration");
5874 		return -1;
5875 	}
5876 
5877 	if (pass == 1) {
5878 		while ((id = queue_remove(id_queue)))
5879 			free(id);
5880 		while ((id = queue_remove(id_queue)))
5881 			free(id);
5882 		if (class_specified)
5883 			while ((id = queue_remove(id_queue)))
5884 				free(id);
5885 		id = queue_remove(id_queue);
5886 		free(id);
5887 		for (l = 0; l < 2; l++) {
5888 			while ((id = queue_remove(id_queue))) {
5889 				free(id);
5890 			}
5891 			id = queue_remove(id_queue);
5892 			if (!id)
5893 				break;
5894 			free(id);
5895 		}
5896 		return 0;
5897 	}
5898 
5899 	rule = malloc(sizeof(struct range_trans_rule));
5900 	if (!rule) {
5901 		yyerror("out of memory");
5902 		return -1;
5903 	}
5904 	range_trans_rule_init(rule);
5905 
5906 	while ((id = queue_remove(id_queue))) {
5907 		if (set_types(&rule->stypes, id, &add, 0))
5908 			goto out;
5909 	}
5910 	add = 1;
5911 	while ((id = queue_remove(id_queue))) {
5912 		if (set_types(&rule->ttypes, id, &add, 0))
5913 			goto out;
5914 	}
5915 
5916 	if (class_specified) {
5917 		if (read_classes(&rule->tclasses))
5918 			goto out;
5919 	} else {
5920 		cladatum = hashtab_search(policydbp->p_classes.table,
5921 		                          "process");
5922 		if (!cladatum) {
5923 			yyerror2("could not find process class for "
5924 			         "legacy range_transition statement");
5925 			goto out;
5926 		}
5927 
5928 		if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE)) {
5929 			yyerror("out of memory");
5930 			goto out;
5931 		}
5932 	}
5933 
5934 	id = (char *)queue_remove(id_queue);
5935 	if (!id) {
5936 		yyerror("no range in range_transition definition?");
5937 		goto out;
5938 	}
5939 	for (l = 0; l < 2; l++) {
5940 		levdatum = hashtab_search(policydbp->p_levels.table, id);
5941 		if (!levdatum) {
5942 			yyerror2("unknown level %s used in range_transition "
5943 			         "definition", id);
5944 			free(id);
5945 			goto out;
5946 		}
5947 		free(id);
5948 
5949 		rule->trange.level[l].sens = levdatum->level->sens;
5950 
5951 		while ((id = queue_remove(id_queue))) {
5952 			if (parse_semantic_categories(id, levdatum,
5953 			                          &rule->trange.level[l].cat)) {
5954 				free(id);
5955 				goto out;
5956 			}
5957 			free(id);
5958 		}
5959 
5960 		id = (char *)queue_remove(id_queue);
5961 		if (!id)
5962 			break;
5963 	}
5964 	if (l == 0) {
5965 		if (mls_semantic_level_cpy(&rule->trange.level[1],
5966 		                           &rule->trange.level[0])) {
5967 			yyerror("out of memory");
5968 			goto out;
5969 		}
5970 	}
5971 
5972 	append_range_trans(rule);
5973 	return 0;
5974 
5975 out:
5976 	range_trans_rule_destroy(rule);
5977 	free(rule);
5978 	return -1;
5979 }
5980 
5981 /* FLASK */
5982