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