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