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