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